Лабы по ПарАлг 2024 / Baraeva_Elizaveta_lb1
.docМИНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В. И. Ульянова (Ленина)
Кафедра МО ЭВМ
отчет
по лабораторной работе №1
по дисциплине «Параллельные алгоритмы»
Тема: Запуск параллельной программы на различном числе
одновременно работающих процессов, упорядочение вывода результатов
Студентка гр. 2383 |
|
Бараева Е. Н. |
Преподаватель |
|
Татаринов Ю. С. |
Санкт-Петербург
2024
Цель работы.
Изучить основы MPI. Написать параллельную программу с использованием MPI. Проанализировать результаты работы с построением графика ускорения/замедления, а также с построением сети Петри.
Задание.
Написать параллельную программу MPI, где каждый процесс определяет свой ранг MPI_Comm_rank (MPI_COMM_WORLD, &ProcRank);, после чего действия в программе разделяются. Все процессы, кроме процесса с рангом 0 else, передают значение своего ранга нулевому процессу MPI_Send (&ProcRank, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);. Процесс с рангом 0 if ( ProcRank == 0 ){...} сначала печатает значение своего ранга printf ("\n Hello from process %3d", ProcRank);, а далее последовательно принимает сообщения с рангами процессов MPI_Recv(&RecvRank, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); и также печатает их значения printf("\n Hello from process %3d", RecvRank); . При этом важно отметить, что порядок приема сообщений заранее не определен и зависит от условий выполнения параллельной программы (более того, этот порядок может изменяться от запуска к запуску).
Запустить программу на 1,2 … N процессах несколько раз.
Проанализировать порядок вывода сообщений на экран. Вывести правило, определяющее порядок вывода сообщений.
Построить график времени работы программы в зависимости от числа запущенных процессов от 1 до 16 Размер шага – например, 4.
Построить график ускорения/замедления работы программы.
Модифицировать программу таким образом, чтобы порядок вывода сообщений на экран соответствовал номеру соответствующего процесса.
Нарисовать сеть Петри для двух вариантов MPI программы.
Выполнение работы.
Написана параллельная программа MPI с замером времени выполнения, в которой несколько процессов принимают сообщения, а один принимает их все и выводит в терминал.
Результаты запуска программы приведены в таблице 1.
Таблица 1 – Запуск программы на разном количестве процессов
Кол-во процессов |
Порядок вывода процессов |
Время работы, с |
1 |
0 |
0.000002 |
2 |
0, 1 |
0.000038 |
3 |
0, 1, 2 |
0.000129 |
0.000176 |
||
4 |
0, 1, 3, 2 |
0.000070 |
0, 2, 1, 3 |
0.000084 |
|
5 |
0, 3, 1, 4, 2 |
0.000132 |
0, 3, 1, 2, 4 |
0.000215 |
|
6 |
0, 3, 5, 2, 1, 4 |
0.000093 |
0, 4, 5, 3, 1, 2 |
0.000116 |
|
7 |
0, 5, 1, 4, 3, 6, 2 |
0.000127 |
0, 1, 4, 5, 3, 6, 2 |
0.000224 |
|
8 |
0, 3, 7, 5, 4, 1, 6, 2 |
0.000157 |
0, 6, 2, 4, 3, 1, 5, 7 |
0.000962 |
|
9 |
0, 1, 5, 6, 2, 4, 8, 3, 7 |
0.000123 |
0, 7, 1, 8, 4, 5, 6, 3, 2 |
0.000601 |
|
10 |
0, 3, 7, 2, 9, 5, 1, 6, 4, 8 |
0.000102 |
0, 6, 1, 4, 7, 8, 3, 2, 9, 5 |
0.000461 |
|
11 |
0, 1, 9, 7, 5, 4, 3, 2, 8, 6, 10 |
0.000144 |
0, 10, 6, 8, 7, 1, 9, 5, 4, 3, 2 |
0.000569 |
|
12 |
0, 10, 5, 11, 4, 3, 6, 9, 8, 2, 1, 7 |
0.000123 |
0, 3, 11, 4, 10, 7, 5, 9, 8, 6, 1, 2 |
0.002324 |
|
13 |
0, 12, 7, 3, 10, 2, 6, 5, 11, 1, 9, 4, 8 |
0.000113 |
0, 8, 11, 1, 9, 4, 5, 12, 10, 7, 6, 3, 2 |
0.000699 |
|
14 |
0, 3, 7, 11, 13, 2, 10, 5, 9, 4, 1, 8, 12, 6 |
0.000487 |
0, 1, 12, 5, 4, 3, 10, 11, 13, 7, 2, 6, 9, 8 |
0.001076 |
|
15 |
0, 11, 14, 10, 7, 6, 9, 8, 1, 13, 5, 3, 2, 4, 12 |
0.000382 |
0, 13, 12, 9, 1, 5, 4, 14, 11, 3, 2, 10, 7, 6, 8 |
0.003438 |
|
16 |
0, 12, 2, 6, 4, 14, 10, 8, 7, 11, 13, 15, 5, 3, 9, 1 |
0.000388 |
0, 15, 9, 7, 1, 3, 11, 14, 6, 2, 10, 12, 4, 8, 13, 5 |
0.003068 |
Анализируя вывод программы, видим, что порядок вывода сообщений может быть любой, исключением является процесс с рангом 0, который всегда выводит своё сообщение первым. На порядок вывода сигналов влияет планировщик задач. Также время выполнения программы сильно варьируется от запуска к запуску. Это происходит, скорее всего, потому что объем вычислительных операций несравнимо мал и поэтому случайные факторы сильно сказываются на времени работы программы.
Сеть Петри см. на рисунке 1.
Рисунок 1 – Сеть Петри для произвольного порядка
T_0,1 – печать сообщения «Hello from process 0» и начало цикла; P_0,1 –итерация цикла приёма сообщений; P_0,2 – сообщение получено. P_𝑖,1 – отправка сообщения в процесс 0; P_𝑖,2 – ожидание приёма сообщения; P_𝑖,3 – подтверждение приёма сообщения; T_𝑖,1 – сообщение отправлено, переход к завершению программы.
Для вывода сообщений процессов в порядке возрастания рангов нужно изменить аргумент MPI_SOURCE_ANY на i, т.е. на ранг процесса.
Сеть Петри см. на рисунке 2.
Рисунок 2 – Сеть Петри с фиксированным порядком
T_0,1 – печать начального сообщения; P_0,1 – ожидание сообщения; P_0,2 – сообщение принято и отправлено подтверждение приёма, P_0,3 – ожидание следующего сообщения; P_0,𝑛+1 – сообщение n принято и отправлено подтверждение приема. P_𝑖,1 – сообщение отправлено, P_𝑖,2 – процесс ожидает подтверждение приёма; P_𝑖,3 – отправлено подтверждение доставки сообщения; T_𝑖,1 – переход к завершению программы.
Разработанный программный код см. в приложении А.
Исследование программы.
Построим график времени работы программы в зависимости от числа запущенных процессов от 1 до 16 (с шагом – 2). Для этого запустим программу по пять раз, и в качестве значения возьмём среднее.
График времени работы программы в зависимости от числа запущенных процессов см. на рисунке 3.
Рисунок 3 – График времени работы программы в зависимости от числа запущенных процессов
По графику видно, что время работы программы возрастает вместе с увеличением количества процессов.
График ускорения/замедления программы см. на рис. 4.
Рисунок 4 – График ускорения/замедления программы
Из графика можно понять, что программа замедляется при увеличении количества процессов. Так получается из-за того, что программа получилась не параллельная, а последовательная.
Вывод.
Были получены навыки работы с протоколом MPI и его реализацией. Написана программа на языке C, использующая возможности MPI. Проведены замеры времени работы программы в зависимости от количества процессов и проанализированы результаты. Построены графики замедления/ускорения и работы программы, а также сети Петри. Было замечено, что программа замедляется при увеличении числа процессов.
ПРИЛОЖЕНИЕ А ИСХОДНЫЙ КОД ПРОГРАММЫ
Название файла: mess.c
#include <stdio.h>
#include "mpi.h"
#define RECV_ORDER 0
int main(int argc, char **argv) {
int proc_rank, num_procs, n;
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) {
printf("Hello from process %3d\n", proc_rank);
time_start = MPI_Wtime();
for (int i = 1; i < num_procs; i++) {
MPI_Recv(&n, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
printf("Hello from process %3d\n", n);
}
time_end = MPI_Wtime();
printf("The program has taken %lf seconds\n", time_end - time_start);
}
else {
MPI_Send(&proc_rank, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
Название файла: order.c
#include <stdio.h>
#include "mpi.h"
#define RECV_ORDER 0
int main(int argc, char **argv) {
int proc_rank, num_procs, n;
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) {
printf("Hello from process %3d\n", proc_rank);
time_start = MPI_Wtime();
for (int i = 1; i < num_procs; i++) {
MPI_Recv(&n, 1, MPI_INT, i, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
printf("Hello from process %3d\n", n);
}
time_end = MPI_Wtime();
printf("The program has taken %lf seconds\n", time_end - time_start);
}
else {
MPI_Send(&proc_rank, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
