Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 11 лет назад пользователемАлиса Алымова
1 Интерфейс передачи сообщений: MPI
2 Базовые архитектуры Массивно-параллельные системы (MPP) Симметричные мультипроцессорные системы (SMP) Системы с неоднородным доступом к памяти (NUMA) Кластерные системы
3 Массивно-параллельные системы (MPP) MPP состоят из однородных вычислительных узлов, включающих один или несколько процессоров локальную память коммуникационный процессор или сетевой адаптер жесткие диски и/или другие устройства ввода/вывода (иногда)
4 Управление массивно- параллельными системами 1) На каждом узле может работать полноценная, UNIX-подобная операционная система, функционирующая отдельно от других узлов 2) Полноценная ОС работает только на управляющей машине, на каждом узле работает сильно урезанный вариант ОС, обеспечивающий работу соответствующей ветви параллельного приложения
5 Схема MPP системы ВУ 1 ВУ... ВУ 2 ВУM ВУN ВУ.. Управляющий узел(ы) Ввод-вывод … ……… … ……
6 Симметричные мультипроцессорные системы (SMP) Общая память Высокоскоростная среда передачи данных CPU
7 Системы с неоднородным доступом к памяти (NUMA) Высокоскоростной коммутатор CPU Память CPU Память CPU Память ……
8 Кластерные системы Узел (ВМ) Высокоскоростная сеть Узел (ВМ) …
9 Этапы создания параллельной программы последовательный алгоритм подвергается распараллеливанию вводятся две дополнительных нематематических операции: прием и передача данных распараллеленный алгоритм записывается в виде программы, в которой операции приема и передачи записываются в терминах конкретной системы связи между ветвями
10 Система связи Система связи включает два компонента: Программный Аппаратный Способы передачи данных: Через разделяемую память В виде сообщений
11 Краткая характеристика MPI Single program/Multiple data (SPMD) Multiple instruction/Multiple data (MIMD)
12 Коммуникаторы, группы и области связи Группа (MPI_Group) Область связи (communication domain) Коммуникатор
13 Обрамляющие функции. Начало и завершение Инициализация библиотеки MPI_Init( &argc, &argv ) Аварийное закрытие библиотеки MPI_Abort( описатель области связи, код ошибки MPI ) Нормальное закрытие библиотеки MPI_Finalize() Информационные функции: сообщают размер группы и порядковый номер вызывающей задачи int size, rank: MPI_Comm_size( MPI_COMM_WORLD, &size ) MPI_Comm_rank( MPI_COMM_WORLD, &rank )
14 Пример: использование MPI_Init, MPI_Finalize, MPI_Comm_size, MPI_Comm_rank #include int main( int argc, char **argv ) { int size, rank, i; … return 0; }
15 int main( int argc, char **argv) MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &size ); MPI_Comm_rank( MPI_COMM_WORLD, &rank ); if( rank==0 ) printf("Total processes count = %d\n", size ); printf("Hello! My rank in MPI_COMM_WORLD = %d\n", rank ); MPI_Barrier( MPI_COMM_WORLD ); if( rank == 0 ) for( puts ("Command line of process 0:"), i=0; i
16 int main( int argc, char **argv) MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &size ); MPI_Comm_rank( MPI_COMM_WORLD, &rank ); if( rank==0 ) printf("Total processes count = %d\n", size ); printf("Hello! My rank in MPI_COMM_WORLD = %d\n", rank ); MPI_Barrier( MPI_COMM_WORLD ); if( rank == 0 ) for( puts ("Command line of process 0:"), i=0; i
17 int main( int argc, char **argv) MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &size ); MPI_Comm_rank( MPI_COMM_WORLD, &rank ); if( rank==0 ) printf("Total processes count = %d\n", size ); printf("Hello! My rank in MPI_COMM_WORLD = %d\n", rank ); MPI_Barrier( MPI_COMM_WORLD ); if( rank == 0 ) for( puts ("Command line of process 0:"), i=0; i
18 int main( int argc, char **argv) MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &size ); MPI_Comm_rank( MPI_COMM_WORLD, &rank ); if( rank==0 ) printf("Total processes count = %d\n", size ); printf("Hello! My rank in MPI_COMM_WORLD = %d\n", rank ); MPI_Barrier( MPI_COMM_WORLD ); if( rank == 0 ) for( puts ("Command line of process 0:"), i=0; i
19 int main( int argc, char **argv) MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &size ); MPI_Comm_rank( MPI_COMM_WORLD, &rank ); if( rank==0 ) printf("Total processes count = %d\n", size ); printf("Hello! My rank in MPI_COMM_WORLD = %d\n", rank ); MPI_Barrier( MPI_COMM_WORLD ); if( rank == 0 ) for( puts ("Command line of process 0:"), i=0; i
20 int main( int argc, char **argv) MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &size ); MPI_Comm_rank( MPI_COMM_WORLD, &rank ); if( rank==0 ) printf("Total processes count = %d\n", size ); printf("Hello! My rank in MPI_COMM_WORLD = %d\n", rank ); MPI_Barrier( MPI_COMM_WORLD ); if( rank == 0 ) for( puts ("Command line of process 0:"), i=0; i
21 Функции пересылки данных способ зацепления процессов автоматический выбор одного из трех вариантов: буферизация на передающей стороне ожидание на приемной стороне ожидание на передающей стороне способ взаимодействия коммуникационного модуля MPI с вызывающим процессом: блокирующий неблокирующий в отдельные функции выделены: создание "канала" для приема/передачи сообщения инициация приема/передачи закрытие канала
22 Функции MPI MPI_Recv и MPI_Send – выполняют блокирующую приемопередачу с автоматическим в ыбором зацепления Функции коллективных коммуникаций: broadcast – один-всем scatter – один-каждому gather – каждый-одному allgather – все-каждому alltoall – каждый-каждому
23 Связь точка-точка. Простейший набор. Пример. Аргументы функций: Адрес буфера Размер буфера Тип ячейки буфера Номер задачи Идентификатор сообщения Описатель области связи Статус завершения приема Задача 1 передает: int buf[10]; MPI_Send( buf, 5, MPI_INT, 1, 0, MPI_COMM_WORLD ); Задача 2 принимает: int buf[10]; MPI_Status status; MPI_Recv( buf, 10, MPI_INT, 0, 0, MPI_COMM_WORLD, &status );
24 Коллективные функции Точки синхронизации, или барьеры Функции коллективного обмена данными Функции поддержки распределенных операций
25 Основные особенности и отличия от коммуникаций типа точка-точка на прием и/или передачу работают одновременно все задачи-абоненты указываемого коммуникатора коллективная функция выполняет одновременно и прием, и передачу как правило, значения ВСЕХ параметров должны быть идентичными во всех задачах MPI назначает идентификатор для сообщений автоматически
26 Функции MPI_Bcast MPI_Bcast( buf, count, dataType, rootRank, communicator ) MPI_Gather (MPI_Gatherv) MPI_Scatter (MPI_Scatterv) MPI_Allgather (MPI_Allgatherv) MPI_Alltoall (MPI_Alltoallv)
27 Точки синхронизации, или барьеры int MPI_Barrier( MPI_Comm comm ) 0 xxxx....xxxxxxxxxxxxxxxxxxxx 1 xxxxxxxxxxxx....xxxxxxxxxxxx 2 xxxxxxxxxxxxxxxxxxxxxx....xx 0 xxxx....xx(xxxxxxxx(||||xxxxxxxx(||xx 1 xxxxxx(||||x....xxxxxxx(xxxxxxxx(||xx 2 xxxxxx(||||xxxxxxxx(||||..xxxxxxxx(xx время Без барьеров: С барьерами: Обозначения: x нормальное выполнение. ветвь простаивает ( вызван MPI_Barrier | MPI_Barrier ждет своего вызова в остальных ветвях
28 Распределенные операции int vector[16]; int resultVector[16]; MPI_Comm_rank( MPI_COMM_WORLD, &myRank ); for( i=0; i
29 Распределенные операции int vector[16]; int resultVector[16]; MPI_Comm_rank( MPI_COMM_WORLD, &myRank ); for( i=0; i
30 Распределенные операции int vector[16]; int resultVector[16]; MPI_Comm_rank( MPI_COMM_WORLD, &myRank ); for( i=0; i
31 Распределенные операции int vector[16]; int resultVector[16]; MPI_Comm_rank( MPI_COMM_WORLD, &myRank ); for( i=0; i
32 Распределенные операции int vector[16]; int resultVector[16]; MPI_Comm_rank( MPI_COMM_WORLD, &myRank ); for( i=0; i
33 Распределенные операции int vector[16]; int resultVector[16]; MPI_Comm_rank( MPI_COMM_WORLD, &myRank ); for( i=0; i
34 Распределенные операции int vector[16]; int resultVector[16]; MPI_Comm_rank( MPI_COMM_WORLD, &myRank ); for( i=0; i
35 Распределенные операции int vector[16]; int resultVector[16]; MPI_Comm_rank( MPI_COMM_WORLD, &myRank ); for( i=0; i
36 Распределенные операции int vector[16]; int resultVector[16]; MPI_Comm_rank( MPI_COMM_WORLD, &myRank ); for( i=0; i
37 Предопределенные описатели операций в MPI MPI_MAX и MPI_MIN ищут поэлементные максимум и минимум; MPI_SUM вычисляет сумму векторов; MPI_PROD вычисляет поэлементное произведение векторов; MPI_LAND, MPI_BAND, MPI_LOR, MPI_BOR, MPI_LXOR, MPI_BXOR - логические и двоичные операции И, ИЛИ, исключающее ИЛИ; MPI_MAXLOC, MPI_MINLOC - поиск индексированного минимума/максимума.
38 Операции Ассоциативные: (a+b)+c = a+(b+c) Коммутативные: a+b = b+a Операции: MPI_Allreduce MPI_Reduce_scatter MPI_Scan
39 Создание коммутаторов и групп Копирование: MPI_Comm tempComm; MPI_Comm_dup( MPI_COMM_WORLD, &tempComm ); MPI_Comm_free( &tempComm ); Расщепление: MPI_Comm_split( existingComm, indexOfNewSubComm, rankInNewSubComm, &newSubComm ); Создание через группы: MPI_Comm_group MPI_Group_xxx MPI_Comm_create MPI_Group_free
40 MPI и типы данных Все функции приемопередачи в MPI оперируют не количеством передаваемых байт, а количеством ячеек В MPI имеется механизм конструирования пользовательских описателей на базе уже имеющихся (как пользовательских, так и встроенных) При создании в MPI сняты ограничения: Ячейки не налезают друг на друга Ячейки не располагаются с разрывами
41 Зачем MPI знать тип передаваемых данных Пользовательские типы данных Приложение MPI может работать на гетерогенном вычислительном комплексе (коллективе ЭВМ с разной архитектурой) Фортрановский тип CHARACTER Структуры в Си
42 Использование MPI Средства автоматической декомпозиции Языки программирования Оптимизированные библиотеки для стандартных языков Средства визуального проектирования Отладчики
43 MPI-1 и MPI-2 Нововведения в MPI-2: Взаимодействие между приложениями. Поддержка механизма "клиент-сервер". Динамическое порождение ветвей Для работы с файлами создан архитектурно- независимый интерфейс Разделяемая память может быть не только каналом связи между ветвями, но и местом совместного хранения данных
44 #include #define tagFloatData 1 #define tagDoubleData 2 #define ELEMS(x) ( sizeof(x) / sizeof(x[0]) ) Пример
45 #include #define tagFloatData 1 #define tagDoubleData 2 #define ELEMS(x) ( sizeof(x) / sizeof(x[0]) ) Пример
46 #include #define tagFloatData 1 #define tagDoubleData 2 #define ELEMS(x) ( sizeof(x) / sizeof(x[0]) ) Пример
47 int main( int argc, char **argv ) { int size, rank, count; float floatData[10]; double doubleData[20]; MPI_Status status; MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &size ); MPI_Comm_rank( MPI_COMM_WORLD, &rank );Пример
48 if (size != 2) { if (rank == 0) printf("Error: two processes required instead of %d, abort\n", size ); MPI_Barrier( MPI_COMM_WORLD ); MPI_Abort(MPI_COMM_WORLD, MPI_ERR_OTHER); return -1; }Пример
49 if (size != 2) { if (rank == 0) printf("Error: two processes required instead of %d, abort\n", size ); MPI_Barrier( MPI_COMM_WORLD ); MPI_Abort(MPI_COMM_WORLD, MPI_ERR_OTHER); return -1; }Пример
50 if (size != 2) { if (rank == 0) printf("Error: two processes required instead of %d, abort\n", size ); MPI_Barrier( MPI_COMM_WORLD ); MPI_Abort(MPI_COMM_WORLD, MPI_ERR_OTHER); return -1; }Пример
51 if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);Пример
52 if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);Пример
53 if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);Пример
54 if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);Пример
55 if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);Пример
56 if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);Пример
57 if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);Пример
58 MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);
59 MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);
60 MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);
61 MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);
62 MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);
63 MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);
64 MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);
65 MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD);
66 MPI_Get_count(&status, MPI_DOUBLE, &count);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD); MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);
67 MPI_Get_count(&status, MPI_DOUBLE, &count);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD); MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);
68 MPI_Get_count(&status, MPI_DOUBLE, &count);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD); MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);
69 MPI_Get_count(&status, MPI_DOUBLE, &count);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD); MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status);
70 printf("Received %d elems\n", count);Пример if (rank == 0) { MPI_Send(floatData, 5, MPI_FLOAT, 1, tagFloatData, MPI_COMM_WORLD); MPI_Send(doubleData, 6, MPI_DOUBLE, 1, tagDoubleData, MPI_COMM_WORLD); } else { MPI_Recv(doubleData, ELEMS(doubleData), MPI_DOUBLE, 0, tagDoubleData, MPI_COMM_WORLD, &status); MPI_Get_count(&status, MPI_DOUBLE, &count);
71 MPI_Recv(floatData, ELEMS(floatData), MPI_FLOAT, 0, tagFloatData, MPI_COMM_WORLD, &status); MPI_Get_count(&status, MPI_FLOAT, &count); } MPI_Finalize(); return 0; }Пример
72 Коллективные функции A0A0 broadcast A0A0 A0A0 A0A0 A0A0 A0A0 A0A0
73 Коллективные функции A0A0 A1A1 A2A2 A3A3 A4A4 A5A5 A0A0 A1A1 A2A2 A3A3 A4A4 A5A5 scatter gather
74 Коллективные функции A0A0 B0B0 C0C0 D0D0 E0E0 F0F0 allgather A0A0 A0A0 A0A0 A0A0 A0A0 A0A0 B0B0 B0B0 B0B0 B0B0 B0B0 B0B0 C0C0 C0C0 C0C0 C0C0 C0C0 C0C0 D0D0 D0D0 D0D0 D0D0 D0D0 D0D0 E0E0 E0E0 E0E0 E0E0 E0E0 E0E0 F0F0 F0F0 F0F0 F0F0 F0F0 F0F0
75 Коллективные функции A0A0 A1A1 A2A2 A3A3 A4A4 A5A5 B0B0 B1B1 B2B2 B3B3 B4B4 B5B5 C0C0 C1C1 C2C2 C3C3 C4C4 C5C5 D0D0 D1D1 D2D2 D3D3 D4D4 D5D5 E0E0 E1E1 E2E2 E3E3 E4E4 E5E5 F0F0 F1F1 F2F2 F3F3 F4F4 F5F5 A0A0 A1A1 A2A2 A3A3 A4A4 A5A5 B0B0 B1B1 B2B2 B3B3 B4B4 B5B5 C0C0 D0D0 E0E0 F0F0 C1C1 C2C2 C3C3 C4C4 C5C5 D1D1 D2D2 D3D3 D4D4 D5D5 E1E1 E2E2 E3E3 E4E4 E5E5 F1F1 F2F2 F3F3 F4F4 F5F5 alltoall
76 Общие функции int MPI_Init( int* argc, char*** argv) int MPI_Finalize( void ) int MPI_Comm_size( MPI_Comm comm, int* size) int MPI_Comm_rank( MPI_comm comm, int* rank) double MPI_Wtime(void) int MPI_Barrier( MPI_Comm comm)
77 Прием-передача-базовые int MPI_{I}Send(void* buf, int count, MPI_Datatype datatype, int dest, int msgtag, MPI_Comm comm{, MPI_Request *request}) int MPI_{I}Recv(void* buf, int count, MPI_Datatype datatype, int source, int msgtag, MPI_comm comm, MPI_Status *status{, MPI_Request *request}) int MPI_Probe( int source, int msgtag, MPI_Comm comm, MPI_Status *status) int MPI_Get_Count( MPI_Status *status, MPI_Datatype datatype, int *count)
78 Асинхронные прием-передача: действия с квитанциями int MPI_Wait( MPI_Request *request, MPI_Status *status) int MPI_WaitAll( int count, MPI_Request *requests, MPI_Status *statuses) int MPI_WaitAny( int count, MPI_Request *requests, int *index, MPI_Status *status) int MPI_WaitSome( int incount, MPI_Request *requests, int *outcount, int *indexes, MPI_Status *statuses)
79 Асинхронные прием-передача: действия с квитанциями int MPI_Test( MPI_Request *request, int *flag, MPI_Status *status) int MPI_TestAll( int count, MPI_Request *requests, int *flag, MPI_STatus *statuses) int MPI_TestAny(int count, MPI_Request *requests, int *index, int *flag, MPI_Status *status) int MPI_TestSome( int incount, MPI_Request *requests, int *outcount, int *indexes, MPI_Status *statuses)
80 Объединение запросов int MPI_Send_Init( void *buf, int count, MPI_Datatype datatype, int dest, int msgtag, MPI_Comm comm, MPI_Request *request) int MPI_Recv_Init( void *buf, int count, MPI_Datatype datatype, int source, int msgtag, MPI_Comm comm, MPI_Request *request) MPI_Start_All( int count, MPI_Request *requests)
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.