Блокирующие обмены данными. Применение функций MPI_Send и MPI_Recv и их разновидностей для обмена данными между MPI-процессами

Наиболее часто используемыми блокирующими функциями передачи данных типа “точка-точка”(peer-to-peer) являются функции MPI_Send и MPI_Recv.

Для передачи сообщения процесс-отправитель выполняет функцию:

int MPI_Send (void *buf, int count, MPI_Datatype type, int dest, int tag, MPI_Comm comm),

где

- buf – адрес буфера памяти, в котором располагаются данные отправляемого сообщения,

- count – количество элементов данных в сообщении,

- type - тип элементов данных пересылаемого сообщения,

- dest - ранг процесса, которому отправляется сообщение,

- tag - значение-тег, используемое для идентификации сообщений(

Arbitrary non-negative integer assigned by the programmer to uniquely identify a message. Send and receive operations should match message tags. For a receive operation, the wild card MPI_ANY_TAG can be used to receive any message regardless of its tag. The MPI standard guarantees that integers 0-32767 can be used as tags, but most implementations allow a much larger range than this.)

- comm - коммуникатор, в рамках которого выполняется передача данных.

Для указания типа пересылаемых данных в MPI имеется ряд базовых типов, полный список которых приведен в табл. 3.4.4.1. 1.

Таблица 3.4.4.1.1. Базовые (пpедопpеделенные) типы данных MPI для языка C

Следует отметить:

1. Отправляемое сообщение определяется через указание блока памяти (буфера), в котором это сообщение располагается. Используемая для указания буфера триада

(buf, count, type)

входит в состав параметров практически всех функций передачи данных,

2. Процессы, между которыми выполняется передача данных, в обязательном порядке должны принадлежать коммуникатору, указываемому в функции MPI_Send,

3. Параметр tag используется только при необходимости различения передаваемых сообщений, в противном случае в качестве значения параметра может быть использовано произвольное целое число (см. также описание функции MPI_Recv).

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

Для приема сообщения процесс-получатель должен выполнить функцию:

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

,где

- buf, count, type – буфер памяти для приема сообщения, назначение каждого отдельного параметра соответствует описанию в MPI_Send,

- source - ранг процесса, от которого должен быть выполнен прием сообщения,

- tag - тег сообщения, которое должно быть принято для процесса,

- comm - коммуникатор, в рамках которого выполняется передача данных,

- status – указатель на структуру данных с информацией о результате выполнения операции приема данных.

Следует отметить:

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

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

3. При необходимости приема сообщения с любым тегом для параметра tag может быть указано значение MPI_ANY_TAG,

4. Параметр status позволяет определить ряд характеристик принятого сообщения:

- status.MPI_SOURCE – ранг процесса-отправителя принятого сообщения,

- status.MPI_TAG - тег принятого сообщения.

Функция, которая возвращает в переменной count количество элементов типа type в принятом сообщении.

MPI_Get_count(MPI_Status *status, MPI_Datatype type, int *count)

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

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


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



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