Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
па-пми / лр-4.docx
Скачиваний:
0
Добавлен:
10.06.2026
Размер:
207.79 Кб
Скачать

Выводы.

В результате лабораторной работы изучены принципы работы коммуникаторов MPI, создание пользовательских операций редукции и влияние способа организации коллективной операции на поведение распределённой программы.

В ходе работы реализована MPI-программа, разделяющая процессы на две группы через MPI_Comm_split, формирующая локальные значения A и выполняющая коллективную редукцию. Это позволяет одновременно получить минимум в одной группе и максимум в другой с последующей доставкой результатов всем процессам через MPI_Allreduce.

Проведены замеры времени и построены два графика: зависимость среднего времени от числа процессов и график замедления. Анализ показал рост среднего времени при увеличении числа процессов и заметное ухудшение параллельной эффективности в больших конфигурациях. Основной причиной этого выступают расходы на создание и управление коммуникаторами, создание пользовательской операции и стоимость глобальной коллективной операции, а также затраты на синхронизацию и возможная конкуренция за CPU.

В качестве формальной модели представлена сеть Петри, фиксирующая стадии подготовки N и A, синхронный вызов MPI_Comm_split, распределение токенов и коллективную фазу редукции MPI_Allreduce.

В заключение, прямая реализация хорошо иллюстрирует работу коммуникаторов и коллективных операций при небольших запусках, при увеличении числа процессов отмечается снижение масштабируемости.

Приложение а Исходный код программы

Main.c

#include "/opt/homebrew/Cellar/open-mpi/5.0.8/include/mpi.h"

#include <stdio.h>

#include <stdlib.h>

#include <float.h>

#include <time.h>

void minmax_op(void *invec, void *inoutvec, int *len, MPI_Datatype *dtype) {

double *in = (double*)invec;

double *inout = (double*)inoutvec;

for (int i = 0; i < *len; ++i) {

if (i == 0) {

if (in[i] < inout[i]) inout[i] = in[i];

} else {

if (in[i] > inout[i]) inout[i] = in[i];

}

}

}

int main(int argc, char *argv[]) {

MPI_Init(&argc, &argv);

int size, rank;

MPI_Comm_size(MPI_COMM_WORLD, &size);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if (size < 2) {

if (rank == 0) fprintf(stderr, "Error: program requires at least 2 processes.\n");

MPI_Finalize();

return 1;

}

int N = (rank % 2) + 1;

unsigned int seed = (unsigned int)time(NULL) + (unsigned int)(rank * 7919);

srand(seed);

double A = ((double)rand() / (double)RAND_MAX) * 100.0;

MPI_Comm group_comm;

MPI_Comm_split(MPI_COMM_WORLD, N, rank, &group_comm);

double local[2];

local[0] = (N == 1) ? A : DBL_MAX;

local[1] = (N == 2) ? A : -DBL_MAX;

double global[2];

MPI_Op op;

MPI_Op_create(&minmax_op, 1, &op);

MPI_Allreduce(local, global, 2, MPI_DOUBLE, op, MPI_COMM_WORLD);

MPI_Op_free(&op);

if (N == 1) {

printf("Process %d (N=1): my value = %.6f, MIN among A in N=1 group = %.6f\n", rank, A, global[0]);

} else {

printf("Process %d (N=2): my value = %.6f, MAX among A in N=2 group = %.6f\n", rank, A, global[1]);

}

MPI_Comm_free(&group_comm);

MPI_Finalize();

return 0;

}

Соседние файлы в папке па-пми