Отложенный запрос можно сформировать для всех режимов обмена, используя подпрограммы MPI_Bsend_init, MPI_Ssend_init и MPI_Rsend_init. Список параметров у них совпадает со списком параметров подпрограммы MPI_Send_init.
Чтобы инициализировать отложенный обмен, необходимо вызвать подпрограмму MPI_Start:
int MPI_Start(MPI_Request *request)
Входным параметром этой подпрограммы является request — запрос на выполнение операции обмена. Вызов MPI_Start после запроса на обмен, созданным MPI_Send_init, инициирует обмен с теми же свойствами, что и вызов подпрограммы MPI_Isend, а вызов MPI_Start после запроса, созданного MPI_Bsend_init, инициирует обмен аналогичный вызову MPI_Ibsend. Сообщение, которое передано операцией, инициированной с помощью MPI_Start, может быть принято любой подпрограммой приема.
Инициализация всех обменов, чьи запросы на выполнение неблокирующей операции обмена отмечены в массиве requests, осуществляется подпрограммой MPI_Startall:
int MPI_Startall(int count, MPI_Request *requests)
Инициированный отложенный обмен завершается вызовом MPI_Wait, MPI_Test и некоторых других подпрограмм.
Аннулировать ожидающие обработки неблокирующие обмены можно с помощью операции MPI_Cancel. Ее можно использовать для освобождения ресурсов, прежде всего памяти, отведенной для размещения буферов:
int MPI_Cancel(MPI_Request *request)
Вызов этой подпрограммы завершается сразу, возможно, еще до реального аннулирования обмена. Аннулируемый обмен следует завершить. Сделать это можно с помощью вызова подпрограмм MPI_Request_free, MPI_Wait, MPI_Test и некоторых других.
Операцию MPI_Cancel можно использовать для аннулирования обменов, использующих как отложенный, так и обычный запрос. После вызова MPI_Cancel и следующего за ним вызова MPI_Wait или MPI_Test запрос на выполнение операции обмена становится неактивным и может быть активизирован для нового обмена. Информация об аннулированной операции содержится в аргументе status.
Подпрограмма MPI_Test_cancelled возвращает значение параметра flag равное true, если обмен, связанный с указанным статусом, успешно аннулирован:
int MPI_Test_cancelled(MPI_Status *status, int *flag)
Аннулирование — трудоемкая операция, не стоит ею злоупотреблять. Запрос на выполнение операции (request) можно аннулировать с помощью подпрограммы MPI_Request_free:
int MPI_Request_free(MPI_Request *request)
При вызове эта подпрограмма помечает запрос на обмен для удаления и присваивает ему значение MPI_REQUEST_NULL. Операции обмена, связанной с этим запросом, дается возможность завершиться, а сам запрос удаляется только после завершения обмена.
Следует учитывать, что после того как запрос аннулирован, нельзя проверить, был ли успешно завершен соответствующий обмен, поэтому активный запрос нельзя аннулировать.
#include "mpi.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
int rank, tag, cnt, N, status(MPI_STATUS_SIZE);
float sndbuf, rcvbuf;
parameter(bufsize = 4 + MPI_BSEND_OVERHEAD);
byte buff(bufsize);
int cnt = 1;
int tag = 0;
sndbuf = 3.14159;
rcvbuf = 0;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
N = 4;
if (rank == 0)
for(i = 0; i < N; i++)
{
MPI_Isend(&sndbuf, cnt, MPI_FLOAT, 1, tag,
MPI_COMM_WORLD, req);
printf("process %i", rank, " send %i\n", sndbuf);
MPI_Request_free(req);
MPI_Irecv(&rcvbuf, cnt, MPI_FLOAT, 1, 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;
}
else
{
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;
for( i=1,i < n – 1,i++)
{
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.