Точечные взаимодействия

27
Точечные взаимодействия

description

Точечные взаимодействия. Назначение точечных взаимодействий. системный буфер. нет буферизации. буфер пользователя. Семантика точечных взаимодействий. Простейшая пересылка. #include #include #define M 3 #define VAL 5 #define ID 1 static int size, rank; - PowerPoint PPT Presentation

Transcript of Точечные взаимодействия

Page 1: Точечные взаимодействия

Точечные взаимодействия

Page 2: Точечные взаимодействия

Назначение точечных взаимодействий

Page 3: Точечные взаимодействия

Семантика точечных взаимодействий

нет буферизации

системный буфер

буфер пользователя

Page 4: Точечные взаимодействия

Простейшая пересылка.

#include <mpi.h>

#include <stdio.h>

#define M 3#define VAL 5#define ID 1

static int size, rank;

void initArray(int* a, int m, int v){

int i;for(i = 0; i < m; i ++) a[i] = v;

}

void printArray(int* a, int m){

int i;printf("[ ");for(i = 0; i < m; i ++) printf("%d ", a[i]);printf("]\n");

}

Page 5: Точечные взаимодействия

int main( int argc, char **argv ){

int dta[M]; MPI_Status status;

MPI_Init( &argc, &argv );

MPI_Comm_size( MPI_COMM_WORLD, &size );MPI_Comm_rank( MPI_COMM_WORLD, &rank );

if( size != 2 ) { if( rank == 0 ) { printf("Error: 2 processes required\n"); fflush(stdout); } MPI_Abort(MPI_COMM_WORLD, MPI_ERR_OTHER ); }

if( rank == 0 ){initArray(dta, M, VAL);

MPI_Send(dta, M, MPI_INT, 1, ID, MPI_COMM_WORLD ); printArray(dta, M);

fflush(stdout); } else {

MPI_Recv(dta, M, MPI_INT, 0, ID, MPI_COMM_WORLD, &status ); printArray(dta, M); fflush(stdout); }

MPI_Finalize();return 0;

}

Page 6: Точечные взаимодействия

Функции обменов точка-точка

int MPI_Send( buf, count, datatype, dest, tag, comm )

void *buf; /* in */int count, dest, tag; /* in */MPI_Datatype datatype; /* in */MPI_Comm comm; /* in */

buf - адрес начала буфера посылаемых данныхcount - число пересылаемых объектов типа, соответствующего datatypedest - номер процесса-приемникаtag - уникальный тэг, идентифицирующий сообщениеdatatype - MPI-тип принимаемых данныхcomm - коммуникатор

Page 7: Точечные взаимодействия

int MPI_Recv( buf, count, datatype, source, tag, comm, status )

void *buf; /* in */int count, source, tag; /* in */MPI_Datatype datatype; /* in */MPI_Comm comm; /* in */MPI_Status *status; /* out */

buf - адрес буфера для приема сообщенияcount - максимальное число объектов типа datatype, которое может быть записано в буферsource - номер процесса, от которого ожидается сообщениеtag - уникальный тэг, идентифицирующий сообщениеdatatype - MPI-тип принимаемых данныхcomm - коммуникаторstatus - статус завершения

Page 8: Точечные взаимодействия

typedef struct{ int count; int MPI_SOURCE; int MPI_TAG; int MPI_ERROR;} MPI_Status;

count - число полученных элементовMPI_SOURCE - ранг процесса-передатчика данныхMPI_TAG - тэг сообщенияMPI_ERROR - код ошибки

Page 9: Точечные взаимодействия

Прием по шаблону

В качестве параметров source и tag в функции MPI_Recv могут быть использованы константы

MPI_ANY_SOURCE и MPI_ANY_TAG

соответственно. Допускается прием от процесса с произвольным номером и/или сообщения с произвольным тэгом.

Page 10: Точечные взаимодействия

Стратегия управляющий-рабочие

M

S

S

S

T

пороговое значение

(гранулярность)

Page 11: Точечные взаимодействия

Недетерминизм за счет разницы в относительных скоростях процессов (race

condition)

Page 12: Точечные взаимодействия

Виды точечных взаимодействий

MPI_Send блокирующая пересылка

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

MPI_Bsend буферизованная пересылка

функция возвращает управление тогда, когда данные скопированы в буфер, выделяемый пользователем

Page 13: Точечные взаимодействия

MPI_Ssend синхронная пересылка

функция возвращает управление тогда, когда процесс-приемник преступил к выполнению соответствующей операции приема

MPI_Rsend интерактивная пересылка

поведение функции не определено, если соответствующая операция приема не начала выполнения (для увеличения производительности)

Page 14: Точечные взаимодействия

Deadlock

if(rank == 0) {

MPI_Ssend(… 1 …)

MPI_Recv(…1…)

} else {

MPI_Ssend(… 0 …)

MPI_Recv(…0…)

}

Page 15: Точечные взаимодействия

«Недетерминированный» deadlock

if(rank == 0) {

MPI_Send(… 1 …)

MPI_Recv(…1…)

} else {

MPI_Send(… 0 …)

MPI_Recv(…0…)

}

Page 16: Точечные взаимодействия

#include <mpi.h>#include <stdio.h>

#define M 3

int main( int argc, char **argv ){

int n;int i;int rank;int size;int *buf;int *abuf;int blen;int ablen;MPI_Status status;

MPI_Init( &argc, &argv );MPI_Comm_size( MPI_COMM_WORLD, &size );MPI_Comm_rank( MPI_COMM_WORLD, &rank );

Page 17: Точечные взаимодействия

if( size != 2 ) { if( rank == 0 ) { printf("Error: 2 processes required\n"); fflush(stdout); } MPI_Abort(MPI_COMM_WORLD, MPI_ERR_OTHER ); }

Page 18: Точечные взаимодействия

if( rank == 0 ){blen = M * (sizeof(int) + MPI_BSEND_OVERHEAD);buf = (int*) malloc(blen);MPI_Buffer_attach(buf, blen);printf("attached %d bytes\n", blen);fflush(stdout);for(i = 0; i < M; i ++) {

printf("starting send %d ...\n", i);fflush(stdout);n = i;

MPI_Bsend(&n, 1, MPI_INT, 1, i, MPI_COMM_WORLD );printf("complete send %d\n", i); fflush(stdout);_sleep(1000);

}MPI_Buffer_detach(&abuf, &ablen);printf("detached %d bytes\n", ablen);free(abuf);

Page 19: Точечные взаимодействия

} else { for(i = M - 1; i >= 0; i --) {

printf("starting recv %d ...\n", i);fflush(stdout); MPI_Recv(&n, M, MPI_INT, 0, i, MPI_COMM_WORLD,

&status );printf("complete recv: %d. received %d\n", i, n); fflush(stdout);

} }

MPI_Finalize();return 0;}

Упражнение. Переписать программу, используя MPI_Ssend.

Page 20: Точечные взаимодействия

Функции работы с буфером обмена

int MPI_Buffer_attach( buffer, size )void *buffer; /* in */int size; /* in */

buffer - адрес начала буфераsize - размер буфера в байтах

int MPI_Buffer_detach( bufferptr, size ) void *bufferptr; /* out */int *size; /* out */

*bufferptr - адрес высвобожденного буфера*size - размер высвобожденного пространства

функция MPI_Buffer_detach блокирует процесс до техпор, пока все данные не отправлены из буфера

Page 21: Точечные взаимодействия

Особенности работы с буфером

•Буфер всегда один.

•Зачем функция MPI_Buffer_detach возвращает адрес освобождаемого буфера?

Page 22: Точечные взаимодействия

Особенности работы с буфером

Page 23: Точечные взаимодействия

Неблокирующая пересылка

int MPI_Isend( buf, count, datatype, dest, tag, comm, request)

MPI_Request *request; /* out */

int MPI_Irecv( buf, count, datatype, source, tag, comm, request )

MPI_Request *request; /* out */

Инициация:

Неблокирующие пересылки позволяют передавать данныепараллельно с вычислениями.

Page 24: Точечные взаимодействия

Завершение:

int MPI_Wait (MPI_Request * request, MPI_Status * status)

int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status)

int MPI_Waitall(int count, MPI_Request array_of_requests[],MPI_Status array_of_statuses[] )

int MPI_Waitany(int count, MPI_Request array_of_requests[],int* index, MPI_Status *status )

Page 25: Точечные взаимодействия

Пример: кольцевой сдвиг данных

Page 26: Точечные взаимодействия

#include "mpi.h"#include <stdio.h>

intmain (argc, argv) int argc; char *argv[];{ int numtasks, rank, next, prev, buf[2], tag1 = 1, tag2 = 2; MPI_Request reqs[4]; MPI_Status stats[4];

MPI_Init (&argc, &argv); MPI_Comm_size (MPI_COMM_WORLD, &numtasks); MPI_Comm_rank (MPI_COMM_WORLD, &rank);

prev = (rank == 0) ? (numtasks - 1) : (rank - 1); next = (rank == (numtasks - 1)) ? 0 : (rank + 1);

Page 27: Точечные взаимодействия

MPI_Irecv (&buf[0], 1, MPI_INT, prev, tag1, MPI_COMM_WORLD, &reqs[0]);

MPI_Irecv (&buf[1], 1, MPI_INT, next, tag2, MPI_COMM_WORLD, &reqs[1]);

MPI_Isend (&rank, 1, MPI_INT, prev, tag2, MPI_COMM_WORLD, &reqs[2]);

MPI_Isend (&rank, 1, MPI_INT, next, tag1, MPI_COMM_WORLD, &reqs[3]);

printf("rank: %d, buf[0]: %d, buf[1]: %d\n",

rank, buf[0], buf[1]);

MPI_Waitall (4, reqs, stats);

MPI_Finalize ();}