Коммуникации точка-точка в MPI


 

В коммуникациях типа «точка-точка» участвуют два процесса (как частный случай процесс может посылать сообщения сам себе). Существуют различные варианты функций отправки и приема сообщений: блокирующие и не блокирующие, с буферизацией, с синхронизацией и по готовности.

Рассмотрим функции блокирующей передачи сообщений – MPI_Send и MPI_Recv:

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

 

Данная функция отправляет данные, находящиеся по адресу buf в количестве count типа datatype процессу с рангом dest с тэгом сообщения tag. Посылка сообщения происходит в коммуникаторе comm. Параметр tag необходим для того, чтобы отличать сообщения от одного и того же процесса, либо сообщения от разных процессов, если принимающий процесс ожидает сообщение от любого процесса.

int MPI_Recv(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Status *status) – Принимает данные и записывает их по адресу buf в количестве count типа datatype от процесса с рангом dest с тэгом сообщения tag. Прием сообщения происходит в коммуникаторе comm. По адресу status в структуру типа MPI_Status записывается информация о прошедшем приеме сообщения.

typedef struct MPI_Status {

int count; //Сколько байт получено

int cancelled; //Была ли передача прервана

int MPI_SOURCE; //От кого сообщение

int MPI_TAG; //Тэг сообщения

int MPI_ERROR; //Код ошибки

} MPI_Status;

 

Функции MPI_Send и MPI_Recv являются блокирующими. Возвращение из MPI_Send не происходит до тех пор, пока данные сообщения не будут скопированы во внутренний буфер MPI. MPI_Recv возвращает управление только после того, как сообщение было принято, таким образом, возможно появление взаимных блокировок процессов (deadlock) - ситуаций при который несколько процессов находятся в состоянии бесконечного ожидания ресурсов, занятых самими этими процессами. Блокировка может произойти в случае, когда два процесса попытаются обменяться сообщениями при помощи одинаковой последовательности вызовов (на примере процессов с рангами 0 и 1):

MPI_Send(buffer, 100, MPI_CHAR, !rank, 1, MPI_COMM_WORLD);

MPI_Recv(buffer, 100, MPI_CHAR, !rank, 1, MPI_COMM_WORLD,&st);

 

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

MPI_Sendrecv_replace:

int MPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,

int dest, int sendtag,

void *recvbuf, int recvcount, MPI_Datatype recvtype,

int source, int recvtag,

MPI_Comm comm, MPI_Status *status)

 

Буфера sendbuf и recvbuf не должны пересекаться. Если необходимо обменяться данными, то следует использовать функцию MPI_Sendrecv_replace.

int MPI_Sendrecv_replace(void *buf, int count, MPI_Datatype datatype,

int dest, int sendtag, int source, int recvtag,

MPI_Comm comm, MPI_Status *status)

Ниже приведен пример обмена данными двух процессов с рангами 0 и 1 при помощи вызова MPI_Sendrecv_replace:

#include <mpi.h>

#include <stdio.h>

static char data[100];

int main(int argc, char** argv)

{

int rank,size;

MPI_Status st;

MPI_Init(&argc, &argv);

MPI_Comm_size(MPI_COMM_WORLD, &size);

MPI_Comm_rank(MPI_COMM_WORLD,&rank);

if (size!=2)

{

printf("This example should be run on 2 processors \n");

MPI_Finalize();

return 0;

}

if(rank==0) {

sprintf(data, “message from process 0 ”);

} else {

sprintf(data, “message from process 1 ”);

} MPI_Sendrecv_replace(&data,100, MPI_INT, !rank, 0,!rank,0,MPI_COMM_WORLD,&st);

printf("Process %d got %s. \n", rank, data);

MPI_Finalize();

return 0;

}

Результат работы:

Process 0 got message from process 1.

Process 1 got message from process 0.



Дата добавления: 2016-05-31; просмотров: 2225;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.012 сек.