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

Презентация:



Advertisements
Похожие презентации
Коллективные взаимодействия процессов. MPI предоставляет ряд функций для коллективного взаимодейстия процессов. Эти функции называют коллективными, поскольку.
Advertisements

Параллельное программирование с использованием технологии MPI Аксёнов Сергей Владимирович к.т.н., доцент каф.ОСУ ТПУ Лекция 8 Томский политехнический университет.
Введение в параллельные вычисления. Технология программирования MPI (день четвертый) Антонов Александр Сергеевич, к.ф.-м.н., н.с. лаборатории Параллельных.
Параллельное программирование с использованием технологии MPI Аксёнов Сергей Владимирович к.т.н., доцент каф.ОСУ ТПУ Лекция 7 Томский политехнический университет.
Введение в параллельные вычисления. Технология программирования MPI (день второй) Антонов Александр Сергеевич, к.ф.-м.н., н.с. лаборатории Параллельных.
Лекция 6 Множественное распараллеливание на Linux кластере с помощью библиотеки MPI 1. Компиляция и запуск программы на кластере. 2. SIMD модель параллельного.
Параллельное программирование с использованием технологии MPI Аксёнов Сергей Владимирович к.т.н., доцент каф.ОСУ ТПУ Лекция 4 Томский политехнический университет.
Кафедра ЮНЕСКО по НИТ1 Коммуникационные операции «точка-точка» параллельное программирование.
Библиотека MPI Message Passing Interface. История MPI Стандарт MPI год, MPI год. Определяет API (варианты для Си, C++, Fortran, Java).
Интерфейс передачи сообщений: MPI. Базовые архитектуры Массивно-параллельные системы (MPP) Симметричные мультипроцессорные системы (SMP) Системы с неоднородным.
Введение в параллельные вычисления. Технология программирования MPI (день третий) Антонов Александр Сергеевич, к.ф.-м.н., н.с. лаборатории Параллельных.
Библиотека MPI Message Passing Interface.
Практические основы параллельного программирования. Посыпкин Михаил Анатольевич
Параллельные аппаратные архитектуры и модели программирования Традиционная архитектура фон Неймана Расширение традиционной архитектуры Сопроцессоры Многоядерные.
Гергель В.П. Общий курс Теория и практика параллельных вычислений Лекция 4 Методы разработки параллельных программ при использования интерфейса передачи.
Кафедра ЮНЕСКО по НИТ1 Передача упакованных данных Параллельное программирование.
Основы параллельного программирования с использованием MPI Лекция 3 Немнюгин Сергей Андреевич Санкт-Петербургский государственный университет физический.
Основы параллельного программирования с использованием MPI Лекция 5 Немнюгин Сергей Андреевич Санкт-Петербургский государственный университет физический.
Основы параллельного программирования с использованием MPI Лекция 4 Немнюгин Сергей Андреевич Санкт-Петербургский государственный университет физический.
MPI за 90 минут Метод погружения Сергей Петрович Нечаев, Сибирский Суперкомпьютерный центр.
Транксрипт:

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

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

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

Простейшая пересылка. #include #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"); }

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

Функции обменов точка-точка 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 - коммуникатор

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

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

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

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

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

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

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

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

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

#include #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 );

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 ){ 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);

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

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

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

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

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

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

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

#include "mpi.h" #include 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);

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