Синтаксис функций приведен ниже:
int MPI_Send(void* message, int count,
MPI_Datatype datatype, int dest, int tag,
MPI_Comm comm)
int MPI_Recv(void* message, int count,
MPI_Datatype datatype, int source, int tag,
MPI_Comm comm, MPI_Status* status)
Содержимое сообщения хранится в блоке памяти, на который указывает
аргумент message. Следующие два аргумента, count
и
datatype, позволяют системе определить конец сообщения:
оно содержит последовательность count значений, каждое из
которых имеет тип данных datatype, который не является встроенным
типом C, хотя большинство предопределенных типов соответствует типам
C. Предопределенные типы MPI и соответствующие типы C
представлены в табл. 8.
Тип MPI | Соответствующий тип С |
MPI_CHAR | signed char |
MPI_SHORT | signed short int |
MPI_INT | signed int |
MPI_LONG | signed long int |
MPI_UNSIGNED_CHAR | unsigned char |
MPI_UNSIGNED_SHORT | unsigned short int |
MPI_UNSIGNED | unsigned int |
MPI_UNSIGNED_LONG | unsigned long int |
MPI_FLOAT | float |
MPI_DOUBLE | double |
MPI_LONG_DOUBLE | long double |
MPI_BYTE | - |
MPI_PACKED | - |
Последние два типа, MPI_BYTE и MPI_PACKED, не соответствуют стандартным типам C. Тип MPI_BYTE используется, если система не должна выполнять преобразование между различными представлениями данных (например, в гетерогенной сети рабочих станций, применяющих различные представления данных). Особенность типов MPI в том, что они позволяют приложениям на гетерогенных архитектурах взаимодействовать единообразно, выполняя необходимые преобразования типов прозрачно для пользователя.
Следует отметить, что количество памяти, выделенной для буфера получения, может точно не соответствовать размеру получаемого сообщении. Например, при работе программы размер сообщения, посылаемый процессом 1 равен strlen (message +1) = 28 символов, а процесс 0 получает сообщение в буфер, который имеет размер 100 символов. В любом случае процесс-получатель не может знать точного размера посланного сообщения. Поэтому MPI позволяет принимать сообщение, пока есть место в выделенной памяти. Если места недостаточно, возникает ошибка выхода за пределы памяти.
Аргументы dest и source соответствуют рангам процессов приема и посылки. MPI позволяет source принимать значение предопределенной константы MPI_ANY_SOURCE, которое может использоваться, если процесс готов получить сообщение от любого иного процесса. Для dest подобной константы нет.
MPI имеет два механизма, предназначенные для разделения пространств сообщении - тэги и коммуникаторы. Аргументы tag и comm соответственно определяют тэг и коммуникатор. Существует групповой тэг MPI_ANY_TAG, определяющий любой тэг для сообщения.
Последний аргумент MPI_Recv(), status, возвращает информацию, относящуюся к фактически полученным данным. Он ссылается на запись с двумя полями: одно - для источника, другое - для тэга. Например, если в качестве источника был указан MPI_ANY_SOURCE, то status будет содержать ранг процесса, который прислал сообщение.
Для посылки сообщений также можно использовать варианты функций MPI_Send(). Эти варианты определяют различные режимы передачи сообщений (стандартный, синхронный, буферизованный и режим передачи по готовности). Информация о режимах приведена в табл. 9.
Название режима | Условие завершения | Функция |
Стандартная передача | Как для синхронной или буферизованной | MPI_SEND |
Синхронная передача | Завершается, когда завершен прием | MPI_SSEND |
Буферизованная передача | Всегда завершается | MPI_BSEND |
Передача по готовности | Всегда завершается | MPI_RSEND |
Прием | Завершается, когда сообщение принято | MPI_RECV |
Буферизованная передача гарантирует немедленное завершение, поскольку сообщение вначале копируется в системный буфер, а затем доставляется. Недостатком ее является необходимость выделения специальных буферов, потребляющих ресурсы системы.
Передача по готовности предполагает инициирование передачи в момент, когда приемник вызывает соответствующий ей прием. Этот режим гарантирует отсутствие в коммуникационной сети блуждающих сообщений.