- •Введение
- •Порядок выполнения и защиты лабораторных работ
- •Лабораторная работа №1. Определение параметров n-мерных коммутационных структур вс типа гиперкуб, тор и циркулянт
- •Приведение схем алгоритмов к виду, удобному для организации параллельных вычислений.
- •Использование граф-схем для представления параллельных алгоритмов
- •Определение контуров в граф-схеме алгоритма
- •Лабораторная работа №4. Построение матрицы логической несовместимости операторов
- •Лабораторная работа №5. Построение множеств взаимно независимых операторов
- •Лабораторная работа №6. Определение ранних и поздних сроков окончания выполнения операторов и оценка снизу требуемого количества процессоров и времени решения задачи на вс
- •Лабораторная работа №8. Написание программ с использованием библиотеки mpi
- •Определение характеристик таймера
- •Приём и передача сообщений
- •Определения структуры приходящего сообщения
- •Определение базовых характеристик коммуникационной сети
- •Анализ тупиковых ситуаций при обмене
- •Организация передачи-приёма сообщений без блокировки
- •Реализация отложенных запросов на взаимодействие
- •Сравнительная оценка различных способов обмена данными
- •Использование глобальных операций в mpi
- •Взаимодействие процессов в mpi
- •Оглавление
Анализ тупиковых ситуаций при обмене
Процессы обмена сообщениями с ближайшими соседями в соответствии с топологией кольца при помощи неблокирующих операций показаны в фрагменте нижеприведенной программы. Заметим, что использование для этих целей блокирующих операций может привести к возникновению тупиковой ситуации.
Пример 10:
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int i,ierr,rank,size,prev,next,buf[2];
MPI_Request reqs[4];
MPI_Status status[4];
double a[5];
int N=5;
ierr=MPI_Init(&argc,&argv);
ierr=MPI_Comm_size(MPI_COMM_WORLD, &size);
ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank==0) prev=size-1; else prev=rank-1;
if (rank==size-1) next=0; else next=rank+1;
ierr=MPI_Irecv(&buf[0],1,MPI_INT,prev,5,MPI_COMM_WORLD,&reqs[0]);
ierr=MPI_Irecv(&buf[1],1,MPI_INT,next,6,MPI_COMM_WORLD, &reqs[1]);
ierr=MPI_Isend(&rank,1,MPI_INT,prev,6,MPI_COMM_WORLD,&reqs[2]);
ierr=MPI_Isend(&rank,1,MPI_INT, next,5, MPI_COMM_WORLD, &reqs[3]);
ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);
ierr=MPI_Waitall (4 , reqs, status) ;
if (rank<size-1){
printf ( "process %i prev=%i next=%i\n",rank,buf[0],buf[1]);
i++;
}
ierr=MPI_Finalize();
}
Задание: Измените программу так, чтобы в передаваемых сообщениях содержалась строка с номером процесса (например, “one”, “two” и т.д.).
Схема использования процедуры MPI_Waitsome демонстрируется в следующем примере.
Пример 11:
#include "mpi.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
int rank, size;
int i, index[4], count, remaining;
int buffer[400];
MPI_Request request[4];
MPI_Status status[4];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (size > 4)
{
printf("Please run with 4 processes.\n");fflush(stdout);
MPI_Finalize();
return 1;
}
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0)
{
for (i=0; i<size * 100; i++)
buffer[i] = i/100;
for (i=0; i<size-1; i++)
{
MPI_Isend(&buffer[i*100], 100, MPI_INT, i+1, 123, MPI_COMM_WORLD, &request[i]);
}
remaining = size-1;
while (remaining > 0)
{
MPI_Waitsome(size-1, request, &count, index, status);
if (count > 0)
{
printf("%d sends completed\n", count);fflush(stdout);
remaining = remaining - count;
}
}
}
else
{
MPI_Recv(buffer, 100, MPI_INT, 0, 123, MPI_COMM_WORLD, &status[0]);
printf("%d: buffer[0] = %d\n", rank, buffer[0]);fflush(stdout);
}
MPI_Finalize();
return 0;
}
Задание: Измените программу так, чтобы при успешном завершении всех передач сообщений процесс 0 посылал остальным процессам сообщение “SENDS COMPLETED” и они, получив получив это сообщение, выводили его.
