1 / 27

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

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

bunny
Download Presentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

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

  3. системный буфер нет буферизации буфер пользователя Семантика точечных взаимодействий

  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"); }

  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; }

  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 - число пересылаемых объектов типа, соответствующего datatype dest - номер процесса-приемника tag - уникальный тэг, идентифицирующий сообщение datatype - MPI-тип принимаемых данных comm - коммуникатор

  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 - статус завершения

  8. typedef struct { int count; int MPI_SOURCE; int MPI_TAG; int MPI_ERROR; } MPI_Status; count - число полученных элементов MPI_SOURCE - ранг процесса-передатчика данных MPI_TAG - тэг сообщения MPI_ERROR - код ошибки

  9. Прием по шаблону В качестве параметров source и tagв функции MPI_Recvмогут быть использованы константы MPI_ANY_SOURCEи MPI_ANY_TAG соответственно.Допускается прием от процесса с произвольным номером и/или сообщения с произвольным тэгом.

  10. пороговое значение (гранулярность) T Стратегия управляющий-рабочие M S S S

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

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

  13. Deadlock if(rank == 0) { MPI_Ssend(… 1 …) MPI_Recv(…1…) } else { MPI_Ssend(… 0 …) MPI_Recv(…0…) }

  14. «Недетерминированный» deadlock if(rank == 0) { MPI_Send(… 1 …) MPI_Recv(…1…) } else { MPI_Send(… 0 …) MPI_Recv(…0…) }

  15. #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 );

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

  17. 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);

  18. } 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.

  19. Функции работы с буфером обмена 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 блокирует процесс до тех пор, пока все данные не отправлены из буфера

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

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

  22. Неблокирующая пересылка Неблокирующие пересылки позволяют передавать данные параллельно с вычислениями. Инициация: 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 */

  23. Завершение: 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 )

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

  25. #include "mpi.h" #include <stdio.h> int main (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);

  26. 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 (); }

More Related