Неблокирующие коммуникационные операции
Использование неблокирующих коммуникационных операций повышает безопасность с точки зрения возникновения тупиковых ситуаций, а также может увеличить скорость работы программы за счет совмещения выполнения вычислительных и коммуникационных операций. Эти задачи решаются разделением коммуникационных операций на две стадии: инициирование операции и проверку завершения операции.
Неблокирующие операции используют специальный скрытый (opaque) объект "запрос обмена" (request) для связи между функциями обмена и функциями опроса их завершения. Для прикладных программ доступ к этому объекту возможен только через вызовы MPI-функций. Если операция обмена завершена, подпрограмма проверки снимает "запрос обмена", устанавливая его в значение MPI_REQUEST_NULL. Снять запрос без ожидания завершения операции можно подпрограммой MPI_Request_free.
Функция передачи сообщения без блокировки MPI_Isend
C:
int MPI_Isend(void* buf, int count, MPI_Datatype datatype, int dest,
int tag, MPI_Comm comm, MPI_Request *request)
IN | buf | - адрес начала расположения передаваемых данных; |
IN | count | - число посылаемых элементов; |
IN | datatype | - тип посылаемых элементов; |
IN | dest | - номер процесса-получателя; |
IN | tag | - идентификатор сообщения; |
IN | comm | - коммуникатор; |
OUT | request | - "запрос обмена". |
Возврат из подпрограммы происходит немедленно (immediate), без ожидания окончания передачи данных. Этим объясняется префикс I в именах функций. Поэтому переменную buf повторно использовать нельзя до тех пор, пока не будет погашен "запрос обмена". Это можно сделать с помощью подпрограмм MPI_Wait или MPI_Test, передав им параметр request.
Функция приема сообщения без блокировки MPI_Irecv
C:
int MPI_Irecv(void* buf, int count, MPI_Datatype datatype, int source,
int tag, MPI_Comm comm, MPI_Request *request)
OUT | buf | - адрес для принимаемых данных; |
IN | count | - максимальное число принимаемых элементов; |
IN | datatype | - тип элементов принимаемого сообщения; |
IN | source | - номер процесса-отправителя; |
IN | tag | - идентификатор сообщения; |
IN | comm | - коммуникатор; |
OUT | request | - "запрос обмена". |
Возврат из подпрограммы происходит немедленно, без ожидания окончания приема данных. Определить момент окончания приема можно с помощью подпрограмм MPI_Wait или MPI_Test с соответствующим параметром request.
Как и в блокирующих операциях часто возникает необходимость опроса параметров полученного сообщения без его фактического чтения. Это делается с помощью функции MPI_Iprobe.
Неблокирующая функция чтения параметров полученного сообщения MPI_Iprobe
C:
int MPI_Iprobe (int source, int tag, MPI_Comm comm, int *flag,
MPI_Status *status)
IN | source | - номер процесса-отправителя; |
IN | tag | - идентификатор сообщения; |
IN | comm | - коммуникатор; |
OUT | flag | - признак завершенности операции; |
OUT | status | - атрибуты опрошенного сообщения. |
Если flag=true, то операция завершилась, и в переменной status находятся атрибуты этого сообщения.
Воспользоваться результатом неблокирующей коммуникационной операции или повторно использовать ее параметры можно только после ее полного завершения. Имеется два типа функций завершения неблокирующих операций: