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

MPI_COMM_WORD, &status);

printf("received: %i\n", bf);

}

MPI_Finalize(); return 0;

}

Размер буфера должен превосходить размер сообщения на величину MPI_BSEND_OVERHEAD. Дополнительное поле используется подпрограммой буферизованной передачи для своих целей.

Если перед выполнением операции буферизованного обмена не выделен буфер, MPI ведет себя так, как если бы с процессом был связан буфер нулевого размера. Работа с таким буфером обычно завершается сбоем программы.

Буферизованный обмен рекомендуется использовать в тех ситуациях, когда программисту требуется больший контроль над распределением памяти. Этот режим удобен и для отладки, поскольку причину переполнения буфера определить легче, чем причину тупика.

5.2.4  Обмен по готовности

По готовности передача начинаться и завершается тогда, когда соответствующий прием уже зарегистрирован. Буфер передачи можно использовать вновь не зависимо от того, вызвана ли подпрограмма приема данного сообщения другим процессом или нет. Если прием не зарегистрирован, то результат выполнения операции не определен. Сообщение просто вводится в коммуникационную сеть в надежде, что адресат его получит, чего может и не случиться. Поведение здесь такое же, как и в операциях стандартного или синхронного обменов. Замена передачи по готовности на стандартную передачу не должна изменить результат выполнения и поведение программы в целом. Измениться может только скорость ее выполнения. Передачу по готовности выполняют с помощью подпрограммы MPI_Rsend, параметры которой совпадают с MPI_Send:

int MPI_Rsend(void *buf, int count, MPI_Datatype

datatype, int dest, int tag, MPI_Comm comm)

Обмен по готовности может увеличить производительность программы, поскольку здесь не используются этапы установки межпроцессных связей и не выполняется буферизация, которые требуют дополнительных затрат времени. Обмен по готовности (рис. 5.4) потенциально опасен, поэтому его используют для увеличения быстродействия тогда, когда правильная работа программы гарантируется логической структурой, полученной методами, описанными в разделе 2.

5.2.5  Подпрограммы-пробники

Получить информацию о сообщении еще до его помещения в буфер приема можно с помощью подпрограмм-пробников (или зондирующих подпрограмм) MPI_Probe и MPI_IProbe. На основании полученной информации принимается решение о дальнейших действиях. Можно, например, выделить буфер приема достаточного размера, определив длину сообщения с помощью подпрограммы MPI_Get_count, которая дает доступ к одному из полей статуса. Если после вызова MPI_Probe следует вызов MPI_Recv с такими же значениями аргументов, что и MPI_Probe, он поместит в буфере приема то же самое сообщение, информация о котором была получена MPI_Probe.


Рисунок 5.4.Структура программы, использующая обмен по готовности.

Подпрограмма MPI_Probe выполняет блокирующую проверку доставки сообщения:

int MPI_Probe(int source, int tag, MPI_Comm comm,

MPI_Status *status)

где

·  source — ранг источника или джокер;

·  tag — значение тега или джокер;

·  comm — имя коммуникатора.

·  status— выходной параметр, содержащий нужную информацию.

Неблокирующая проверка сообщения выполняется подпрограммой:

int MPI_Iprobe(int source, int tag, MPI_Comm comm,

int *flag, MPI_Status *status)

Входные параметры те же, что и у подпрограммы MPI_Probe, а выходные flag — имя флага и status — статус. Если сообщение уже поступило и может быть принято, переменнаяflag получает значение true. Проверка приема может выполняться с помощью MPI_Iprobe неоднократно. Нет необходимости выполнять прием сообщения сразу же после его поступления. Пример использования блокирующего зондирования приведен в тексте 5.6.

Текст 5.6. Использование блокирующего зондирования

#include "mpi.h"

#include <stdio.h>

int main(int argc, char *argv[])

{

int rank, i, k, tag, dest, status(MPI_STATUS_SIZE);

float x;

int tag = 0;

int dest = 2;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

if (myrank ==0)