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

Проверки завершения любого числа обменов выполняются с помощью подпрограмм MPI_Waitany и MPI_Testany. Первая подпрограмма блокирует выполнение вызвавшего ее процесса до тех пор, пока хотя бы один обмен из массива запросов (requests) не будет завершен. Индекс соответствующего элемента в массиве requests возвращается в аргументе index, а статус — в аргументе status:

int MPI_Waitany(int count, MPI_Request requests[],

int *index, MPI_Status *status)

Входной параметр count определяет количество элементов в массиве requests, а выходной параметр index (целое от 0 до count-1) определяет статус (status) запроса.

Если запрос на выполнение операции был сформирован неблокирующей операцией обмена, то ему присваивается значение MPI_REQUEST_NULL. Если в списке нет активных запросов или он пуст, то вызов процедуры завершаются сразу со значением индекса MPI_UNDEFINED и пустым статусом.

Подпрограмма MPI_Testany проверяет выполнение любого ранее инициализированного обмена:

int MPI_Testany(int count, MPI_Request requests[],

int *index, int *flag, MPI_Status *status)

К параметрам этой подпрограммы, в отличие от параметров подпрограммы MPI_Waitany, добавлен аргумент flag, который принимает значение true, если одна из операций завершена. Блокирующая подпрограмма MPI_Waitany и неблокирующая MPI_Testany взаимозаменяемы.

Аналогичная пара подпрограмм: MPI_Waitsome и MPI_Testsome, действуют так же как и предыдущая, но флаг получает значение true, когда завершается более одного обмена. Возвращаются индексы, статусы и количество всех завершенных обменов:

intMPI_Waitsome(intincount, MPI_Requestrequests[],

int *outcount, int indices[], MPI_Status statuses[])

Параметр incount определяет общее количество запросов. Через outcount возвращается количество выполненных запросов из массива requests. Массив indices в своих первых outcount элементах содержит индексы завершенных операций. Массив statuses в своих первых outcount элементах содержит статус завершенных операций. Если выполненный запрос был сформирован неблокирующей операцией обмена, то он аннулируется. Если в списке нет активных запросов, выполнение подпрограммы завершается сразу, а параметру outcount присваивается значение MPI_UNDEFINED.

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

int MPI_Testsome(int incount, MPI_Request requests[],

   int *outcount, int indices[], MPI_Status statuses[])

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

5.2.10  Отложенные обмены

Достаточно часто приходится сталкиваться с ситуацией, когда обмены с одинаковыми параметрами выполняются повторно, например, в цикле. В этом случае можно объединить аргументы подпрограмм обмена в один отложенный запрос, который затем повторно используется для инициализации и выполнения обмена сообщениями. Отложенный запрос на выполнение неблокирующей операции обмена позволяет минимизировать накладные расходы на организацию связи между процессором и контроллером связи.

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

Для создания отложенного запроса на обмен используются четыре подпрограммы. Сам обмен они не выполняют. Запрос для стандартной передачи, создается при вызове подпрограммы MPI_Send_init:

int MPI_Send_init(void *buf, int count,

MPI_Datatype datatype, int dest, int tag,

MPI_Comm comm, MPI_Request *request)

Ее входные параметры:

·  buf — адрес буфера передачи;

·  count — количество элементов;

·  datatype — тип элементов;

·  dest — ранг адресата;

·  tag — тег сообщения;

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

Выходным параметром является request — запрос на выполнение операции обмена.