Функция приема сообщения с блокировкой и функция приема сообщения без блокировки

Функция приема сообщения с блокировкой:

int MPI_Recv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status);

где:

OUT buf – адрес начала расположения принимаемого сообщения;

count – максимальное число принимаемых элементов;

datatype – тип элементов принимаемого сообщения;

source – номер процесса-отправителя или MPI_ANY_SOURCE;

tag – числовой идентификатор сообщения или MPI_ANY_TAG;

comm – идентификатор группы;

OUT status –параметры принятого сообщения (описание типа MPI_Status см. в п. 3.1 при первом упоминании в описании параметров функции MPI_Wait).

Функция выполняет прием count элементов типа datatype сообщения с идентификатором tag от процесса с номером source в группе с идентификатором comm.

Число элементов в принимаемом сообщении не должно превосходить значения count. Если число принятых элементов меньше значения count, то гарантируется, что в буфере buf изменятся только элементы, соответствующие элементам принятого сообщения. Попытка считать сообщение с параметром count меньше, чем число элементов в буфере, приводит к потере сообщения.

Блокировка гарантирует, что после возврата из функции все элементы сообщения будут уже приняты и расположены в буфере buf.

В качестве номера процесса-отправителя можно указать предопределенную константу MPI_ANY_SOURCE – признак того, что подходит сообщение от любого процесса. В качестве идентификатора принимаемого сообщения можно указать константу MPI_ANY_TAG – признак того, что подходит сообщение с любым числовым идентификатором.

Примечание. Следует отметить асимметрию между операциями посылки и приема. Операция приема допускает получение сообщения от произвольного отправителя, в то время как в операции посылки должен быть указан уникальный числовой идентификатор процесса-получателя.

Пример №3 (в качестве практического занятия дописать).

Дано: процессу №0 (значение переменной «int NP;») необходимо принять значение в одну переменную «double a;» с любого другого процесса. Передача в данном примере не рассматривается, но известно, что процесс с №1 примерно в это же время передал одно значение типа double процессу №0.

if(_ _ _ _ _ _)

{

MPI_Recv(_ _ _ _

}

(конец примера №3)

Если заранее невозможно определить число count – максимально возможное количество принимаемых элементов, то можно воспользоваться следующей функцией.

Функция для определения параметров поступающего сообщения без его чтения с блокировкой:

int MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status *status);

где:

source – номер процесса-отправителя или MPI_ANY_SOURCE;

tag – числовой идентификатор ожидаемого сообщения или MPI_ANY_TAG;

comm – идентификатор группы;

OUT status – параметры обнаруженного сообщения.

Функция MPI_Probe выполняется с блокировкой, поэтому завершится она лишь тогда, когда сообщение с подходящим идентификатором и номером процесса-отправителя будет доступно для получения. Следует обратить внимание, что функция определяет только факт прихода сообщения, но реально его не принимает.

С помощью возвращенной информации в переменной status (и вызова MPI_Get_count) пользователь может выделить необходимый объем памяти для буфера приёма (для функции MPI_Probe).

Функция приема сообщения без блокировки:

int MPI_Irecv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request);

где:

OUT buf – адрес начала буфера приема сообщения;

count – максимальное число элементов в принимаемом сообщении;

datatype – тип элементов принимаемого сообщения;

source – номер процесса-отправителя или MPI_ANY_SOURCE;

tag – числовой идентификатор принимаемого сообщения или MPI_ANY_TAG;

comm – идентификатор группы;

OUT request – значение, используемое при завершении операции приема.

Прием сообщения аналогичен MPI_Recv, однако возврат из функции происходит сразу после инициализации процесса приема без ожидания получения сообщения в буфере buf. Окончание процесса приема можно определить с помощью параметра request и функций MPI_Wait и MPI_Test.

Как и в блокирующих операциях часто возникает необходимость опроса параметров полученного сообщения без его фактического чтения (до фактического чтения). Это делается с помощью функции MPI_Iprobe.

Функция для определения поступления сообщения и определения параметров поступленного сообщения без его чтения без блокировки:

int MPI_Iprobe(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status);

где:

source – номер процесса-отправителя или MPI_ANY_SOURCE;

tag – числовой идентификатор ожидаемого сообщения или MPI_ANY_TAG;

comm – идентификатор группы;

OUT flag – признак завершенности операции обмена;

OUT status – параметры обнаруженного сообщения.

Получение информации о поступлении и структуре ожидаемого сообщения без блокировки (и может вызываться несколько раз перед получением сообщения). В параметре flag возвращается значение 1 (логическое TRUE), если сообщение с подходящими номером процесса-отправителя, идентификатором сообщения и идентификатором группы уже может быть принято. В этом случае ее действие полностью аналогично действию функции MPI_Probe. В параметре flag возвращается значение 0 (логическое FALSE), если сообщения с указанными атрибутами еще нет.

Для определения числа фактически полученных (или доступных для получения) элементов сообщения необходимо использовать специальную функцию:

int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count);

где:

status – параметры сообщения;

datatype – тип элементов принятого сообщения;

OUT count – число полученных элементов (иногда может принимать значение MPI_UNDEFINED).

Функция MPI_Get_count может быть вызвана либо после чтения сообщения при помощи функций MPI_Recv, MPI_Irecv, либо после опроса факта поступления сообщения при помощи функций MPI_Probe, MPI_Iprobe.

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

  1. Функции ожидания завершения семейства WAIT блокируют работу процесса до полного завершения операции.
  2. Функции проверки завершения семейства TEST возвращают значения TRUE или FALSE в зависимости от того, завершилась операция или нет. Они не блокируют работу процесса и полезны для предварительного определения факта завершения операции.
  3. Функции снятия запроса без ожидания завершения операции.

В случае приема, параметры и длину полученного сообщения можно определить обычным образом с помощью параметра status.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: