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

Выводы.

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

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

Были проведены измерения времени работы программы и построены график зависимости среднего времени от числа процессов и график замедления. Анализ графиков показал, что время выполнения растёт при увеличении числа процессов, так как доминируют накладные расходы на коммуникации, сетевая латентность и частичная сериализация из-за блокирующих операций, что усиливается дисбалансом нагрузки у чётных рангов и конкуренцией за ресурсы при использовании флага --oversubscribe.

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

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

Main.c

#include <mpi.h>

#include <stdio.h>

#include <stdlib.h>

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

MPI_Init(&argc, &argv);

MPI_Comm world = MPI_COMM_WORLD;

int world_size, world_rank;

MPI_Comm_size(world, &world_size);

MPI_Comm_rank(world, &world_rank);

if (world_size % 2 != 0) {

if (world_rank == 0)

fprintf(stderr, "Error: number of processes must be even.\n");

MPI_Finalize();

return EXIT_FAILURE;

}

int K = world_size;

int *degree = (int*) calloc(K, sizeof(int));

int total_edges = 0;

for (int r = 0; r < K; ++r) {

int deg = 0;

if (r % 2 == 1) {

deg = 1;

} else {

if (r - 2 >= 0) deg++;

if (r + 2 < K) deg++;

if (r + 1 < K) deg++;

}

degree[r] = deg;

total_edges += deg;

}

int *index = (int*) malloc(sizeof(int) * K);

int cum = 0;

for (int i = 0; i < K; ++i) {

cum += degree[i];

index[i] = cum;

}

int *edges = (int*) malloc(sizeof(int) * total_edges);

int pos = 0;

for (int r = 0; r < K; ++r) {

if (r % 2 == 1) {

edges[pos++] = r - 1;

} else {

if (r - 2 >= 0) edges[pos++] = r - 2;

if (r + 2 < K) edges[pos++] = r + 2;

if (r + 1 < K) edges[pos++] = r + 1;

}

}

MPI_Comm graph_comm;

MPI_Graph_create(world, K, index, edges, 0, &graph_comm);

int my_rank;

MPI_Comm_rank(graph_comm, &my_rank);

int A = my_rank * 10 + 5;

int nbr_count;

MPI_Graph_neighbors_count(graph_comm, my_rank, &nbr_count);

int *nbrs = (int*) malloc(sizeof(int) * (nbr_count > 0 ? nbr_count : 1));

if (nbr_count > 0) {

MPI_Graph_neighbors(graph_comm, my_rank, nbr_count, nbrs);

}

int *recvd_vals = (int*) malloc(sizeof(int) * (nbr_count > 0 ? nbr_count : 1));

for (int i = 0; i < nbr_count; ++i) {

int partner = nbrs[i];

int recvbuf = -1;

MPI_Status status;

MPI_Sendrecv(&A, 1, MPI_INT, partner, 0, &recvbuf, 1, MPI_INT, partner, 0, graph_comm, &status);

recvd_vals[i] = recvbuf;

}

if (nbr_count > 0) {

int *ranks_arr = (int*) malloc(sizeof(int) * nbr_count);

int *vals_arr = (int*) malloc(sizeof(int) * nbr_count);

for (int i = 0; i < nbr_count; ++i) {

ranks_arr[i] = nbrs[i];

vals_arr[i] = recvd_vals[i];

}

for (int i = 0; i < nbr_count - 1; ++i) {

for (int j = 0; j < nbr_count - 1 - i; ++j) {

if (ranks_arr[j] > ranks_arr[j+1]) {

int tr = ranks_arr[j]; ranks_arr[j] = ranks_arr[j+1]; ranks_arr[j+1] = tr;

int tv = vals_arr[j]; vals_arr[j] = vals_arr[j+1]; vals_arr[j+1] = tv;

}

}

}

printf("Process = %d A = %d, from neighbors:", my_rank, A);

for (int i = 0; i < nbr_count; ++i) {

printf(" %d", vals_arr[i]);

}

printf("\n");

free(ranks_arr);

free(vals_arr);

} else {

printf("Process = %d A = %d, dont have neighbors.\n", my_rank, A);

}

free(nbrs);

free(recvd_vals);

MPI_Comm_free(&graph_comm);

free(degree);

free(index);

free(edges);

MPI_Finalize();

return EXIT_SUCCESS;

}

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