Параллельное программирование: Учебное пособие, страница 101

MPI_Isend(&sndbuf, cnt, MPI_FLOAT, 0, tag,

MPI_COMM_WORLD, req);

printf("process %i ", rank,

" send %i\n ", sndbuf);

MPI_Request_free (req);

MPI_Irecv(&rcvbuf, cnt, MPI_FLOAT, 0, tag,

MPI_COMM_WORLD, req);

printf("process %i ", rank,

" yet not received %i\n ", rcvbuf);

MPI_Wait(req, status);

printf("process %i ", rank,

" received %i\n ", rcvbuf);

rcvbuf = 0;

}

MPI_Isend(&sndbuf, cnt, MPI_FLOAT, 0, tag,

MPI_COMM_WORLD, req);

printf("process %i ", rank, " send %i\n ", sndbuf);

MPI_Wait(req, status);

}

MPI_Finalize();

return 0;

}

Результат выполнения этой программы следующий:

mpiexec –host -machinefile -n 2 – myprogr

process 1 yet not received  0.

process 1 received  3.14159012

process 1 send  3.14159012

process 1 yet not received  0.

process 1 received  3.14159012

process 1 send  3.14159012

process 1 yet not received  0.

process 1 received  3.14159012

process 1 send  3.14159012

process 1 yet not received  0.

process 1 received  3.14159012

process 1 send  3.14159012

process 0 send  3.14159012

process 0 yet not received  0.

process 0 received  3.14159012

process 0 send  3.14159012

process 0 yet not received  0.

process 0 received  3.14159012

process 0 send  3.14159012

process 0 yet not received  0.

process 0 received  3.14159012

process 0 send  3.14159012

process 0 yet not received  0.

process 0 received  3.14159012

В первой строке распечатки результата процесс 1 еще не принял нужного значения из буфера

Вызов подпрограммы MPI_Wait, который завершает прием, прерывается, если начинается прием сообщения. Если передача неблокирующая, прием будет завершен, даже если источник не вызывал подпрограмму завершения передачи. Аналогично, вызов MPI_Wait завершится, если начнется прием сообщения. Пример в тексте 5.11.a.

Текст 5.11.а. Использование подпрограммы MPI_Wait

#include “mpi.h”

#include <stdio.h>

main(int argc, char* argv[])

 {

  int         rank, tag1, tag2, cnt;

  int         status(MPI_STATUS_SIZE);

  MPI_Request request;

  float       sndbuf1, sndbuf2, rsvbuf1, rsvbuf2;

  cnt = 1;

  tag1 = 1;

  tag2 = 2;

  sndbuf1 = 3.14159;

  sndbuf2 = 2.71828;

  MPI_Init(&argc, &argv);

  MPI_Comm_rank(MPI_COMM_WORLD, rank);

  if (rank == 0)

    {

      MPI_Ssend(sndbuf1, cnt, MPI_FLOAT, 1, tag1,

                                      MPI_COMM_WORLD);

      Printf("Process ", rank, " send ", sndbuf1);

      MPI_Send(sndbuf2, cnt, MPI_FLOAT, 1, tag2,

                                      MPI_COMM_WORLD);

      Printf("Process ", rank, " send ", sndbuf2);

    }

  else

    {

      MPI_Irecv(rcvbuf1, cnt, MPI_REAL, 0, tag1,

                              MPI_COMM_WORLD, request);

      MPI_Recv(rcvbuf2, cnt, MPI_REAL, 0, tag2,

                              MPI_COMM_WORLD, status);

      Printf("Process ", rank, " received before wait",

                                              rcvbuf1);

      Printf("Process ", rank, " received before wait",

                                              rcvbuf2);

      MPI_Wait(request, status);

      Printf("process ", rank,. " received after wait",

                                              rcvbuf1);

      Printf("process ", rank, " received after wait",

                                              rcvbuf2);

    }

   MPI_Finalize();

  } /* main */

При выполнении этой программы первая синхронная передача процессом с рангом 0 должна завершиться после того, как процесс с рангом 1 зарегистрирует соответствующий неблокирующий прием, даже если дело еще не дошло до вызова подпрограммы MPI_Wait. Процесс с рангом 0 выполнит вторую передачу, дав возможность процессу с рангом 1 завершить передачу. Вывод программы выглядит так:

mpiexec –host -machinefile -n 2 – myprogr

Process 0 send  3.14159012

Process 0 send  2.71828008

Process 1 received before wait 2.08672428

Process 1 received before wait 2.71828008