Int ProcNum, ProcRank, RecvRank;
MPI_Status Status; // Эта переменная нужна используется при
// вызове функций MPI_Send и MPI_Recv
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ProcNum);
MPI_Comm_rank(MPI_COMM_WORLD, &ProcRank);
if ( ProcRank == 0 ) // Если это процесс с рангом 0
{
printf ("\n Hello from process %3d", ProcRank);
// Цикл по всем номерам процессов, начиная с первого:
for ( int i=1; i<ProcNum; i++ )
{
// Ждем приема сообщения от любого процесса:
MPI_Recv(&RecvRank, 1, MPI_INT, MPI_ANY_SOURCE,
MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
printf("\n Hello from process %3d", RecvRank);
} // for
} // if
else // Если это процесс с ненулевым рангом,
// Отсылаем сообщение нулевому процессу:
MPI_Send(&ProcRank,1,MPI_INT,0,0,MPI_COMM_WORLD);
MPI_Finalize();
Return 0;
} // main()
Как следует из текста программы, каждый процесс определяет свой ранг, после чего действия в программе разделяются. Все процессы, кроме процесса с рангом 0, передают значение своего ранга нулевому процессу. Процесс с рангом 0 сначала печатает значение своего ранга, а далее последовательно принимает сообщения с рангами процессов и также печатает их значения.
В функции MPI_Send каждый процесс с ненулевым рангом отсылает данные, расположенные начиная с адреса переменной ProcRank. Размер отправляемого сообщения равен одному значению типа MPI_INT. Таким образом, в передаваемом сообщении фактически отсылается значение переменной ProcRank. Для каждого из отсылающих процессов это значение будет различным и равным рангу процесса.
Функция MPI_Recv принимает сообщение от процесса с любым рангом (на что указывает параметр MPI_ANY_SOURCE). Поскольку нулевой процесс знает, что, кроме него, запущено (ProcNum-1) процессов, он может позволить себе последовательно (в цикле) принять ровно (ProcNum-1) сообщений.
Функция MPI_Recv предполагает, что в любом принятом сообщении будет содержаться ровно один элемент данных типа MPI_INT. Идентичность структуры отправляемого и принимаемого сообщений обязательно должна быть согласована при написании функций MPI_Send и MPI_Recv. Недопустимо, чтобы размер передаваемого сообщения отличался (например, был больше) от размера принимаемого сообщения. Функция MPI_Recv не знает о размере передаваемого сообщения и способна принять только то количество данных, которое указано в ее параметрах.
В нашем примере принимаемое сообщение (один элемент типа MPI_INT) кладется функцией MPI_Recv в переменную RecvRank, после чего распечатывается на экране функцией printf. Следует понимать, что каждый процесс выполняет один и тот же программный код и обладает собственной переменной RecvRank, однако практически использует эту переменную только процесс с рангом ноль. Остальными процессами данная переменная не используется и лишь занимает оперативную память.
Важно отметить, что порядок приема сообщений заранее не определен и зависит от условий выполнения параллельной программы (более того, этот порядок может изменяться от запуска к запуску). Так, возможный вариант результатов печати процесса 0 может состоять в следующем (для параллельной программы из четырех процессов):
Дата добавления: 2016-02-02; просмотров: 1236;