#include <stdio.h>
int main(int argc, char *argv[])
{
int myrank, size, message;
int TAG = 0;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
message = myrank;
if((myrank % 2) == 0) /* Результат деления на 2 равен 0? */
{ /* Отсылка сообщения от процесса четного ранга к нечетному */
if((myrank + 1) != size) /* Ранг процесса нечетный? */
MPI_Send(&message, 1, MPI_INT, myrank + 1, TAG,
MPI_COMM_WORLD);
}
else/* Прием сообщения процессом нечетного ранга */
{if(myrank != 0) /* от передавшего процесса четного ранга */
MPI_Recv(&message, 1, MPI_INT, myrank - 1, TAG,
MPI_COMM_WORLD, &status);
printf("received : %i\n", message);
}
MPI_Finalize();
return 0;
}
Результат выполнения этой программы в случае запуска 10 процессов на 10 процессорах, имена которых перечислены в файле machines.txt, выглядит так:
mpiexec –host -machinefile -n 10 -- myprogr
received : 0
received : 6
received : 2
received : 4
received : 8
Порядок вывода сообщений может оказаться и другим, так как при параллельном выполнении этих 10 процессов скорости выполнения у каждого процесса различны и не предсказуемы.
Если стандартная передача не может быть выполнена из-за недостаточного объема приемного буфера, осуществление процесса блокируется до тех пор, пока не будет доступен буфер достаточного размера. Иногда это может оказаться удобным. Например, когда источник циклически посылает новые значения адресату и они вырабатываются быстрее, чем потребитель может их принять, то через некоторое может произойти переполнение буфера приема. Чтобы этого не допустить, в программу необходимо включить дополнительную синхронизацию. В стандартной передаче такая синхронизация выполняется автоматически.
Недостаточный размер буфера может привести и к тупиковой ситуации. Это иллюстрируется примерами текстов 5.3 и 5.4.
#include "mpi.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
int rank, tag, cnt, status(MPI_STATUS_SIZE);
float sndbuf1, sndbuf2, rcvbuf;
int cnt = 1;
int tag = 0;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (rank == 0)
{
sndbuf1 = 3.14159;
MPI_Send(&sndbuf1, cnt, MPI_FLOAT, 1, tag,
MPI_COMM_WORLD);
printf("Process %i",rank, " send %f\n", sndbuf1);
MPI_Recv(&rcvbuf, cnt, MPI_FLOAT, 1, tag,
MPI_COMM_WORLD, status)
printf("Process %i",rank,"received %f\n",rcvbuf);
}
else
{
MPI_Recv(&rcvbuf, cnt, MPI_FLOAT, 0, tag,
MPI_COMM_WORLD, status);
printf("Process %i",rank,"received %f\n",rcvbuf);
sndbuf2 = 2.71828;
MPI_Send(&sndbuf2, cnt, MPI_FLOAT, 0, tag,
MPI_COMM_WORLD);
Printf("Process %i",rank," send %f\n", sndbuf2)
};
MPI_Finalize(); return 0;
}
Вывод этой программы будет выглядеть так:
mpiexec –host HM1, HM2 -n 2 -- myprogr
Process 1 received 3.14159012
Process 1 send 2.71828008
Process 0 send 3.14159012
Process 0 received 2.71828008
#include "mpi.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
int rank, tag, cnt, status(MPI_STATUS_SIZE);
float sndbuf, rcvbuf;
int tag = 0;
sndbuf = 3.14159;
int cnt = 1;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (rank == 0)
then
{
MPI_Recv(&rcvbuf, cnt, MPI_FLOAT, 1, tag,
MPI_COMM_WORLD, status)
MPI_Send(&sndbuf, cnt, MPI_FLOAT, 1, tag,
MPI_COMM_WORLD);
}
else
{
MPI_Recv(&rcvbuf, cnt, MPI_FLOAT, 0, tag,
MPI_COMM_WORLD, status);
MPI_Send(sndbuf2, cnt, MPI_FLOAT, 0, tag,
MPI_COMM_WORLD);
};
MPI_Finalize();
return 0;
}
Первая из этих программ работает нормально, а вторая попадет в "тупик", так как в ней прием сообщения процессом с рангом 0 должен завершиться до передачи им своего сообщения. Этот прием может быть осуществлен, только если процессом с рангом 1 выполнена соответствующая передача, а она, в свою очередь, может начаться только после завершения процессом 1 приема сообщения от процесса 0.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.