Добавил:
baraevaliza
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабы по ПарАлг 2024 / Baraeva_Elizaveta_lb3
.pdf
МИНОБРНАУКИ РОССИИ
САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ
ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
«ЛЭТИ» ИМ. В. И. УЛЬЯНОВА (ЛЕНИНА)
Кафедра МО ЭВМ
ОТЧЕТ
по лабораторной работе №3
по дисциплине «Параллельные алгоритмы»
Тема: Использование аргументов-джокеров
Студентка гр. 2383
Бараева Е. Н.
Преподаватель
Татаринов Ю. С.
Санкт-Петербург
2024

2
Цель работы.
Изучить использование аргументов-джокеров. Написать параллельную
программу с использованием данных аргументов. Проанализировать
результаты работы с построением графика ускорения/замедления, а также с
построением сети Петри.
Задание.
Вариант 2
Имитация посылки пакета с маршрутом. Процесс 0 генерирует
сообщение, которое состоит из маршрутной и информационной части.
Маршрутная часть содержит последовательность номеров процессов –
промежуточных адресатов. Промежуточный адресат, получив пакет, убирает
из адресной части свой номер и передает сообщение дальше согласно списку.
Окончательный адресат, получив посылку, отчитывается перед процессом 0.
Выполнение работы.
Написана программа MPI с замером времени выполнения, в которой
генерируется сообщение состоящие из маршрутной и информационной
частей. Нулевой процесс отправляет посылку первому процессу из
маршрутной части, затем этот процесс отправляет следующему и т.д.
Последний процесс, получив посылку, отчитывается перед процессом 0.
Время выполнения программы приведено в таблице 1.
Таблица 1 – Время выполнения программы на разном количестве процессов
Кол-во процессов
Время работы, с
Кол-во процессов
Время работы, с
2
0.000113
10
0.001012
3
0.000223
11
0.001603
4
0.000285
12
0.001357
5
0.000369
13
0.002021
6
0.000483
14
0.005335
7
0.000781
15
0.005915
8
0.000952
16
0.011672
9
0.000907

3
Вывод программы на 5 процессах см. рис. 1.
Рисунок 1 – Вывод программы
Анализируя вывод программы, видим, что некоторые строки выведены в
неправильном порядке. Это происходит, скорее всего, потому что объем
вычислительных операций несравнимо мал и поэтому случайные факторы
сильно сказываются на выводе программы.
Сеть Петри см. рис. 2.
Рисунок 2 – Сеть Петри

4
i, j, … , n – номера процессов; W – процесс 0 ожидает отправки отчета;
S_0,i – сообщение от 0 процесса отправлено i процессу; D_0,i – сообщение от
0 процесса получено i процессом; D_n,0 – сообщение от n процесса получено
0 процессом, завершение программы.
Разработанный программный код см. в приложении А.
Исследование программы.
Построим график времени работы программы в зависимости от числа
запущенных процессов от 2 до 16 см. рис. 3.
Рисунок 3 – График времени работы программы в зависимости от числа
запущенных процессов
По графику видно, что время работы программы возрастает вместе с
увеличением количества процессов. Сильнее всего это заметно после 12
процесса. Это связано с тем, что в процессоре устройства 12 ядер.
График ускорения/замедления программы см. на рис. 4.

5
Рисунок 4 – График ускорения/замедления программы
Из графика можно понять, что программа замедляется при увеличении
количества процессов. Это связано с тем, что программа по сути является не
параллельной, а последовательной.
Вывод.
В ходе лабораторной работы было изучено использование аргументовджокеров. Написана программа на языке C++. Проведены замеры времени
работы программы в зависимости от количества процессов и
проанализированы результаты. Построены графики замедления/ускорения и
работы программы, а также построена сеть Петри. Также было замечено, что
программа замедляется при увеличении числа процессов.

6
ПРИЛОЖЕНИЕ А
ИСХОДНЫЙ КОД ПРОГРАММЫ
Название файла: lb3.cpp
#include <iostream>
#include <deque>
#include <vector>
#include <string>
#include <random>
#include <algorithm>
#include <mpi.h>
#define MAX_STRING_LEN 100
void print_vector(std::vector<int> vec) {
for (auto i : vec)
std::cout << i << ' ';
std::cout << std::endl;
}
int main(int argc, char *argv[]) {
int proc_rank, num_procs;
double time_start = 0.0, time_end;
MPI_Status Status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
if (proc_rank == 0) {
std::string info_message = "Привет мир!";
std::vector<int> route;
// Составление маршрутной части сообщения
for (int i = 1; i < num_procs; ++i)
route.push_back(i);
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(route.begin(), route.end(), g);
route.push_back(0);
std::cout << "Маршрут: ";
print_vector(route);
// Отправление сообщения первому адресату
time_start = MPI_Wtime();
MPI_Send(route.data(), route.size(), MPI_INT, route[0], 0,
MPI_COMM_WORLD);
MPI_Send(info_message.c_str(), MAX_STRING_LEN, MPI_CHAR,
route[0], 1, MPI_COMM_WORLD);
}
if (proc_rank > 0) {
// Получение сообщения от адресанта

7
std::vector<int> route(num_procs, 0);
char info_message_buffer[MAX_STRING_LEN];
MPI_Recv(route.data(), route.size(), MPI_INT,
MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &Status);
MPI_Recv(info_message_buffer, MAX_STRING_LEN, MPI_CHAR,
MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, &Status);
std::cout << "Процесс " << proc_rank << " получил
сообщение: " << info_message_buffer << " " << std::endl;
// Удаление номера из маршрутной части сообщения
route.erase(route.begin());
print_vector(route);
// Отправление сообщения следующему адресату
MPI_Send(route.data(), route.size(), MPI_INT, route[0], 0,
MPI_COMM_WORLD);
MPI_Send(info_message_buffer, MAX_STRING_LEN, MPI_CHAR,
route[0], 1, MPI_COMM_WORLD);
}
if (proc_rank == 0) {
// Получение финального сообщения
char final_message[MAX_STRING_LEN];
MPI_Recv(final_message, MAX_STRING_LEN, MPI_CHAR,
MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, &Status);
std::cout << "Процесс 0 получил финальное сообщение: " <<
final_message << std::endl;
time_end = MPI_Wtime();
printf("The program has taken %lf seconds\n", time_end -
time_start);
}
MPI_Finalize();
return 0;
}
Соседние файлы в папке Лабы по ПарАлг 2024
