- Основы двухточечной связи
- Коллективные основы
- Matlab
- Mpi становится стандартом.
- Mpi. терминология и обозначения
- Ocaml
- Python
- Аппаратное обеспечение
- Будущее
- Дальнейшее чтение
- Джава
- Динамическое управление процессами
- История
- Коллективные взаимодействия процессов
- Коммуникатор
- Концепции
- Обертки компилятора
- Обзор
- Общая языковая инфраструктура
- Общие процедуры mpi
- Объединение запросов на взаимодействие
- Официальные реализации
- Предопределенные константы типа элементов сообщений
- Прием/передача сообщений без блокировки
- Прием/передача сообщений с блокировкой
- Пример программы
- Принятие mpi-2
- Производные типы данных
- Работа с группами процессов
- Синхронизация процессов
- Совмещенные прием/передача сообщений
- Сравнение с pvm.
- Сравнение с низкоуровневыми пересылками.
- Функциональность
- Языковые привязки
- Ввод / вывод
Основы двухточечной связи
Ряд важных функций MPI включает связь между двумя конкретными процессами. Популярным примером является то MPI_Send, что позволяет одному указанному процессу отправлять сообщение второму указанному процессу. Двухточечные операции, как их называют, особенно полезны при структурированном или нерегулярном обмене данными, например, в архитектуре параллельных данных, в которой каждый процессор регулярно обменивает области данных с конкретными другими процессорами между этапами вычислений, или ведущий- ведомая архитектура, в которой ведущее устройство отправляет новые данные задачи ведомому всякий раз, когда предыдущая задача завершена.
MPI-1 определяет механизмы как для блокирующих, так и для неблокирующих механизмов связи точка-точка, а также так называемый механизм «готовой отправки», посредством которого запрос на отправку может быть сделан только тогда, когда соответствующий запрос приема уже был сделан. .
Коллективные основы
Коллективные функции включают взаимодействие между всеми процессами в группе процессов (что может означать весь пул процессов или определенное программой подмножество). Типичная функция – MPI_Bcastзвонок (сокращение от « трансляция »).
Эта функция берет данные с одного узла и отправляет их всем процессам в группе процессов. Обратная операция – это MPI_Reduceвызов, который берет данные от всех процессов в группе, выполняет операцию (например, суммирование) и сохраняет результаты на одном узле.
Другие операции выполняют более сложные задачи, например, MPI_Alltoallпереупорядочивают n элементов данных таким образом, что n- й узел получает n- й элемент данных от каждого.
Matlab
Существует несколько академических реализаций MPI с использованием MATLAB . MATLAB имеет собственную библиотеку параллельных расширений, реализованную с использованием MPI и PVM .
Mpi становится стандартом.
Несколько вычислительнх устройств (процессоров), по нынешней терминологии, могут быть объединены одним из трех способов:
- через общую память. В Юниксе существуют средства для работы с ней (разные для BSD- и ATT-клонов Юникса);
- через скоростную внутримашинную сеть на ЭВМ с аппаратной архитектурой MPI. Здесь стандарта нет ;
- через сеть, как правило, работающую по протоколу TCP/IP.
Программный инструментарий MPI разрабатывался как долгожданный стандарт для машин с одноименной аппаратной архитектурой. Задачей-максимум было “подмять” под него и стандарты из соседних пунктов: MPI может работать на базе любого из трех способов соединений.
Тем не менее, первая редакция MPI стандартом не стала в силу следующего ограничения: все процессы, сообщающиеся между собой посредством функций MPI, начинают и заканчивают свое выполнение ОДНОВРЕМЕННО. Это не мешает использовать MPI как скелет для параллельных приложений, но системы массового обслуживания (клиент-серверные приложения и проч.) приходится разрабатывать на базе старого инструментария.
Проблема устранена в MPI-II: он гарантировано станет стандартом в категории 2. Не исключено, что и стандарты категорий 1 и 3 со временем потеряют интерес для программиста и будут использоваться только как интерфейс между “железом” и MPI-II.
Mpi. терминология и обозначения
MPI – message passing interface – библиотека функций, предназначенная
для поддержки работы параллельных процессов в терминах передачи сообщений.
Номер процесса – целое неотрицательное число,
являющееся уникальным
атрибутом каждого процесса.
Атрибуты сообщения – номер процесса-отправителя, номер процесса-получателя
и идентификатор сообщения. Для них заведена структура MPI_Status,
содержащая три поля: MPI_Source (номер процесса отправителя), MPI_Tag
(идентификатор сообщения), MPI_Error (код ошибки); могут быть и
добавочные поля.
Идентификатор сообщения (msgtag) – атрибут сообщения, являющийся
целым неотрицательным числом, лежащим в диапазоне от 0 до 32767. Процессы объединяются в группы, могут быть вложенные группы. Внутри
группы все процессы перенумерованы.
С каждой группой ассоциирован свой
коммуникатор. Поэтому при осуществлении пересылки необходимо указать
идентификатор группы, внутри которой производится эта пересылка. Все процессы
содержатся в группе с предопределенным идентификатором MPI_COMM_WORLD.
Ocaml
Модуль OCamlMPI реализует большое количество функций MPI и активно используется в научных вычислениях. Программа OCaml, состоящая из 11 000 строк, была «преобразована в MPI» с использованием этого модуля, с дополнительными 500 строками кода и небольшой реструктуризацией и работала с превосходными результатами на 170 узлах суперкомпьютера.
Python
Реализации MPI в Python включают: pyMPI , mpi4py, pypar, MYMPI и подмодуль MPI в ScientificPython . pyMPI примечателен тем, что это вариант интерпретатора python, в то время как модуль pypar, MYMPI и ScientificPython являются модулями импорта. Они поручают кодеру решать, кому MPI_Initпринадлежит вызов .
Недавно библиотеки Boost C приобрели Boost: MPI, который включает привязки MPI Python. Это особенно помогает при смешивании C и Python. По состоянию на октябрь 2021 года Boost: привязки MPI Python по-прежнему содержат нефиксированные ошибки упаковки в CentOS .
Аппаратное обеспечение
Аппаратные исследования MPI фокусируются на реализации MPI непосредственно в аппаратном обеспечении, например, через процессор в памяти , встраивая операции MPI в микросхему микросхем RAM в каждом узле. Подразумевается, что этот подход не зависит от языка, операционной системы и процессора, но не может быть легко обновлен или удален.
Другой подход заключался в добавлении аппаратного ускорения к одной или нескольким частям операции, включая аппаратную обработку очередей MPI и использование RDMA для прямой передачи данных между памятью и сетевым интерфейсом без вмешательства процессора или ядра ОС.
Будущее
Некоторые аспекты будущего MPI кажутся убедительными; другие в меньшей степени. MPI Forum вновь созвана в 2007 году для уточнения некоторых MPI-2 вопросы и изучить разработки для возможного MPI-3, в результате чего в версии MPI-3.0 (сентябрь 2021) и MPI-3.1 (июнь 2021).
Архитектуры меняются за счет большего внутреннего параллелизма ( многоядерный ), лучшего детального управления параллелизмом (многопоточность, сходство) и большего количества уровней иерархии памяти . Многопоточные программы могут легче использовать преимущества этих разработок, чем однопоточные приложения.
Это уже привело к появлению отдельных дополнительных стандартов для симметричной многопроцессорной обработки , а именно OpenMP . MPI-2 определяет, как соответствующие стандарту реализации должны решать проблемы с многопоточностью, но не требует, чтобы реализации были многопоточными или даже поточно-ориентированными.
Астрофизик Джонатан Дурси написал статью, в которой назвал MPI устаревшим, указав на новые технологии, такие как язык Chapel , Unified Parallel C , Hadoop , Spark и Flink .
Дальнейшее чтение
- Эта статья основана на материалах, взятых из Free On-line Dictionary of Computing до 1 ноября 2008 г. и включенных в соответствии с условиями «перелицензирования» GFDL версии 1.3 или новее.
- Аояма, Юкия; Накано, июн (1999) RS / 6000 SP: Практическое программирование MPI , ITSO
- Фостер, Ян (1995) Проектирование и создание параллельных программ (онлайн) Addison-Wesley ISBN 0-201-57594-9 , глава 8 Интерфейс передачи сообщений
- Wijesuriya, Viraj Brian (2021-12-29) Daniweb: Пример кода для умножения матриц с использованием подхода параллельного программирования MPI
- Использование серии MPI :
- Гропп, Уильям; Ласк, Юинг; Скьеллум, Энтони (1994). Использование MPI: переносимое параллельное программирование с интерфейсом передачи сообщений . Кембридж, Массачусетс, США: Серия научных и инженерных вычислений MIT Press . ISBN 978-0-262-57104-3.
- Гропп, Уильям; Ласк, Юинг; Скьеллум, Энтони (1999a). Использование MPI, 2-е издание: переносимое параллельное программирование с интерфейсом передачи сообщений . Кембридж, Массачусетс, США: Серия научных и инженерных вычислений MIT Press . ISBN 978-0-262-57132-6.
- Гропп, Уильям; Ласк, Юинг; Скьеллум, Энтони (1999b). Использование MPI-2: Расширенные возможности интерфейса передачи сообщений . MIT Press . ISBN 978-0-262-57133-3.
- Гропп, Уильям; Ласк, Юинг; Скьеллум, Энтони (2021). Использование MPI, 3-е издание: переносимое параллельное программирование с интерфейсом передачи сообщений . Кембридж, Массачусетс, США: Серия научных и инженерных вычислений MIT Press . ISBN 978-0-262-52739-2.
- Гропп, Уильям; Ласк, Юинг; Скьеллум, Энтони (1996). «Высокопроизводительная портативная реализация интерфейса передачи сообщений MPI». Параллельные вычисления . 22 (6): 789–828. CiteSeerX 10.1.1.102.9485 . DOI : 10.1016 / 0167-8191 (96) 00024-5 .
- Пачеко, Питер С. (1997) Параллельное программирование с MPI . [1] 500 стр. ISBN Моргана Кауфмана 1-55860-339-5 .
- MPI – Полная серия справочных материалов :
- Снир, Марк; Отто, Стив У .; Хусс-Ледерман, Стивен; Уокер, Дэвид В .; Донгарра, Джек Дж. (1995) MPI: Полный справочник . MIT Press, Кембридж, Массачусетс, США. ISBN 0-262-69215-5
- Снир, Марк; Отто, Стив У .; Хусс-Ледерман, Стивен; Уокер, Дэвид В .; Донгарра, Джек Дж. (1998) MPI – Полная справка: Том 1, Ядро MPI . MIT Press, Кембридж, Массачусетс. ISBN 0-262-69215-5
- Гропп, Уильям; Хусс-Ледерман, Стивен; Ламсдэйн, Эндрю; Ласк, Юинг; Ницберг, Билл; Сапфир, Уильям; и Снир, Марк (1998) MPI – Полный справочник: Том 2, Расширения MPI-2 . MIT Press, Кембридж, Массачусетс ISBN 978-0-262-57123-4
- Фирузиаан, Мохаммад; Номменсен, О. (2002) Параллельная обработка через MPI и OpenMP , Linux Enterprise, 10/2002
- Ваннески, Марко (1999) Парадигмы для научных вычислений В трудах Европейской школы вычислительной химии (1999, Перуджа, Италия), номер 75 в конспектах лекций по химии , страницы 170–183. Спрингер, 2000 г.
- Bala, Bruck, Cypher, Elustondo, A Ho, CT Ho, Kipnis, Snir (1995) ″ Портативная и настраиваемая библиотека коллективной связи для масштабируемых параллельных компьютеров »в IEEE Transactions on Parallel and Distributed Systems, ″ vol. 6, no. 2 , pp. 154–164, февраль 1995 г.
Джава
Хотя Java не имеет официальной привязки MPI, несколько групп пытаются объединить их с разной степенью успеха и совместимости. Одной из первых попыток была mpiJava Брайана Карпентера, по сути, набор оболочек Java Native Interface (JNI) для локальной библиотеки C MPI, что привело к гибридной реализации с ограниченной переносимостью, которая также должна быть скомпилирована для конкретной используемой библиотеки MPI. .
Однако в этом исходном проекте также определен mpiJava API ( де-факто MPI API для Java, который точно следует эквивалентным привязкам C ), который был принят в других последующих проектах Java MPI. Один из менее используемых API – это MPJ API, который был разработан, чтобы быть более объектно-ориентированным и приближенным к соглашениям о кодировании Sun Microsystems .
Помимо API, библиотеки Java MPI могут либо зависеть от локальной библиотеки MPI, либо реализовывать функции передачи сообщений в Java, в то время как некоторые, такие как P2P-MPI, также обеспечивают одноранговую функциональность и позволяют работать со смешанной платформой.
Некоторые из наиболее сложных частей Java / MPI возникают из-за таких характеристик Java, как отсутствие явных указателей и линейное адресное пространство памяти для его объектов, что делает перенос многомерных массивов и сложных объектов неэффективным.
Обходные обычно включают передачу одной линии в то время , и / или при выполнении явного де- сериализации и литье на оба передающие и принимающие концах, имитируя C или Fortran-подобные массивам путем использованием одномерного массива, а указатели на примитивные типы, использование одноэлементных массивов, что привело к созданию стилей программирования, весьма далеких от соглашений Java.
Еще одна система передачи сообщений Java – MPJ Express. Последние версии могут быть выполнены в кластерной и многоядерной конфигурациях. В кластерной конфигурации он может выполнять параллельные Java-приложения в кластерах и облаках. Здесь сокеты Java или специализированные межсоединения ввода-вывода, такие как Myrinet, могут поддерживать обмен сообщениями между процессами MPJ Express.
Он также может использовать собственную реализацию MPI на языке C, используя собственное устройство. В многоядерной конфигурации параллельное приложение Java выполняется на многоядерных процессорах. В этом режиме процессы MPJ Express представлены потоками Java.
Динамическое управление процессами
Ключевым аспектом является «способность процесса MPI участвовать в создании новых процессов MPI или устанавливать связь с процессами MPI, которые были запущены отдельно». Спецификация MPI-2 описывает три основных интерфейса, с помощью которых процессы MPI могут динамически устанавливать связь MPI_Comm_spawn, MPI_Comm_accept/ MPI_Comm_connectи MPI_Comm_join.
MPI_Comm_spawnИнтерфейс позволяет процесс MPI порождать количество экземпляров названного процесса MPI. Вновь созданный набор процессов MPI формирует новый MPI_COMM_WORLDинтракоммуникатор, но может связываться с родителем и интеркоммуникатором, возвращаемым функцией.
История
Работа над интерфейсом передачи сообщений началась летом 1991 года, когда небольшая группа исследователей начала обсуждение в горном ретрите в Австрии. Результатом этого обсуждения стал семинар по стандартам передачи сообщений в среде с распределенной памятью, состоявшийся 29–30 апреля 1992 г.
в Вильямсбурге, штат Вирджиния . Участники Williamsburg обсудили основные функции, необходимые для стандартного интерфейса передачи сообщений, и создали рабочую группу для продолжения процесса стандартизации. Джек Донгарра , Тони Хей и Дэвид Уолкер выдвинули предварительный проект предложения «MPI1» в ноябре 1992 года.
В ноябре 1992 года в Миннеаполисе состоялась встреча рабочей группы MPI, на которой было решено поставить процесс стандартизации на более высокий уровень. формальная основа. Рабочая группа MPI собиралась каждые 6 недель в течение первых 9 месяцев 1993 года.
Проект стандарта MPI был представлен на конференции Supercomputing ’93 в ноябре 1993 года. После периода публичных комментариев, которые привели к некоторым изменениям в MPI, версия 1.0 MPI был выпущен в июне 1994 года. Эти встречи и обсуждения по электронной почте вместе составляли форум MPI, членство в котором было открыто для всех членов сообщества высокопроизводительных вычислений .
В MPI участвовало около 80 человек из 40 организаций, в основном из США и Европы. Большинство основных производителей компьютеров для параллельной работы участвовали в разработке MPI, сотрудничая с исследователями из университетов, государственных лабораторий и промышленности .
MPI предоставляет поставщикам параллельного оборудования четко определенный базовый набор процедур, которые можно эффективно реализовать. В результате поставщики оборудования могут использовать этот набор стандартных низкоуровневых подпрограмм для создания высокоуровневых подпрограмм для среды связи с распределенной памятью, поставляемой с их параллельными машинами .
Пытаясь создать универсальный стандарт для передачи сообщений, исследователи не основывали его на единой системе, а включили в него наиболее полезные функции нескольких систем, в том числе разработанных IBM, Intel , nCUBE , PVM, Express, P4 и PARMACS. .
Парадигма передачи сообщений привлекательна из-за широкой переносимости и может использоваться при обмене данными для мультипроцессоров с распределенной и общей памятью, сетей рабочих станций и комбинации этих элементов. Парадигма может применяться в нескольких параметрах, независимо от скорости сети или архитектуры памяти.
Поддержка встреч MPI была частично предоставлена DARPA и Национальным научным фондом США (NSF) в рамках гранта ASC-9310330, Соглашения о сотрудничестве между научным и технологическим центром NSF номер CCR-8809615, а также Европейской комиссией через проект Esprit Project P6643. Университет Теннесси также финансовые взносы в MPI Forum.
Коллективные взаимодействия процессов
В операциях коллективного взаимодействия процессов участвуют все процессы
коммуникатора. Соответствующая процедура должна быть вызвана каждым процессом,
быть может, со своим набором параметров. Возврат из процедуры коллективного
взаимодействия может произойти в тот момент, когда участие процесса в данной
операции уже закончено.
Как и для блокирующих процедур, возврат означает
то, что разрешен свободный доступ к буферу приема или посылки, но не означает
ни того, что операция завершена другими процессами, ни даже того, что она
ими начата (если это возможно по смыслу операции).
int MPI_Bcast(void *buf, int count, MPI_Datatype datatype,
int source, MPI_Comm comm)
- OUT buf – адрес начала буфера посылки сообщения
- count – число передаваемых элементов в сообщении
- datatype – тип передаваемых элементов
- source – номер рассылающего процесса
- comm – идентификатор группы
Рассылка сообщения от процесса source всем процессам, включая
рассылающий процесс. При возврате из процедуры содержимое буфера buf
процесса source будет скопировано в локальный буфер процесса. Значения
параметров count, datatype и source должны быть одинаковыми
у всех процессов.
Коммуникатор
Объекты коммуникатора соединяют группы процессов в сеансе MPI. Каждый коммуникатор дает каждому включенному процессу независимый идентификатор и упорядочивает содержащиеся в нем процессы в упорядоченной топологии . MPI также имеет явные группы, но они в основном хороши для организации и реорганизации групп процессов до создания другого коммуникатора.
MPI понимает операции внутрикоммуникаторной отдельной группы и двустороннюю межкоммуникаторную связь. В MPI-1 наиболее распространены одиночные групповые операции. Двусторонние операции чаще всего появляются в MPI-2, где они включают коллективное общение и динамическое внутрипроцессное управление.
Коммуникаторы можно разделить с помощью нескольких команд MPI. Эти команды включают MPI_COMM_SPLIT, где каждый процесс присоединяется к одному из нескольких цветных субкоммуникаторов, объявляя себя имеющим этот цвет.
Концепции
MPI предоставляет несколько функций. Следующие ниже концепции обеспечивают контекст для всех этих возможностей и помогают программисту решить, какие функции использовать в своих прикладных программах. Четыре из восьми основных концепций MPI уникальны для MPI-2.
Обертки компилятора
mpicc (и аналогично mpic , mpif90 и т. д.) – это программа, которая оборачивает существующий компилятор для установки необходимых флагов командной строки при компиляции кода, использующего MPI. Обычно он добавляет несколько флагов, которые позволяют скомпилировать код и связать его с библиотекой MPI.
Обзор
MPI – это протокол связи для программирования параллельных компьютеров . Поддерживаются как двухточечная, так и коллективная связь. MPI «представляет собой интерфейс прикладного программиста с передачей сообщений, вместе с протоколом и семантическими спецификациями, указывающими, как его функции должны вести себя в любой реализации».
MPI не санкционирован каким-либо крупным органом по стандартизации; тем не менее, он стал де-факто стандартом для взаимодействия между процессами, моделирующими параллельную программу, работающую в системе с распределенной памятью . Реальные суперкомпьютеры с распределенной памятью, такие как компьютерные кластеры, часто запускают такие программы.
Основная модель MPI-1 не имеет концепции разделяемой памяти , а MPI-2 имеет только ограниченную концепцию распределенной разделяемой памяти . Тем не менее, программы MPI регулярно запускаются на компьютерах с общей памятью, и как MPICH, так и Open MPI могут использовать общую память для передачи сообщений, если она доступна.
Разработка программ на основе модели MPI (в отличие от явных моделей разделяемой памяти ) имеет преимущества перед архитектурами NUMA, поскольку MPI поощряет локальность памяти . Явное программирование с разделяемой памятью было введено в MPI-3.
Хотя MPI относится к уровням 5 и выше эталонной модели OSI , реализации могут охватывать большинство уровней с сокетами и протоколом управления передачей (TCP), используемыми на транспортном уровне.
Большинство реализаций MPI состоят из определенного набора подпрограмм, вызываемых напрямую из C , C , Fortran (т. Е. API) и любого языка, способного взаимодействовать с такими библиотеками, включая C # , Java или Python .
Преимуществами MPI перед более старыми библиотеками передачи сообщений являются переносимость (поскольку MPI был реализован почти для каждой архитектуры распределенной памяти) и скорость (поскольку каждая реализация в принципе оптимизирована для оборудования, на котором она работает).
MPI использует независимые от языка спецификации (LIS) для вызовов и привязок языков. Первый стандарт MPI определял привязки ANSI C и Fortran-77 вместе с LIS. Проект был представлен на Supercomputing 1994 (ноябрь 1994 г.) и вскоре после этого был доработан. Около 128 функций составляют стандарт MPI-1.3, который был выпущен в качестве последнего конца серии MPI-1 в 2008 году.
В настоящее время стандарт имеет несколько версий: версия 1.3 (обычно сокращенно MPI-1 ), которая подчеркивает передачу сообщений и имеет статическую среду выполнения, MPI-2.2 (MPI-2), которая включает новые функции, такие как параллельный ввод-вывод, динамическое управление процессами и операции с удаленной памятью, а также MPI-3.1 (MPI-3), который включает расширения для коллективных операций с неблокирующими версиями и расширения для односторонних операций.
LIS MPI-2 определяет более 500 функций и предоставляет языковые привязки для ISO C , ISO C и Fortran 90 . Также была добавлена возможность взаимодействия объектов, чтобы упростить программирование передачи сообщений на разных языках. Побочным эффектом стандартизации MPI-2, завершенной в 1996 году, было уточнение стандарта MPI-1, создание MPI-1.2.
MPI-2 в основном является надмножеством MPI-1, хотя некоторые функции устарели. Программы MPI-1.3 по-прежнему работают в реализациях MPI, соответствующих стандарту MPI-2.
MPI-3 включает новые привязки Fortran 2008, но при этом удаляет устаревшие привязки C , а также многие устаревшие процедуры и объекты MPI.
MPI часто сравнивают с Parallel Virtual Machine (PVM), которая представляет собой популярную распределенную среду и систему передачи сообщений, разработанную в 1989 году и являющуюся одной из систем, которая мотивировала необходимость стандартной параллельной передачи сообщений.
Модели потокового программирования с общей памятью (такие как Pthreads и OpenMP ) и программирование с передачей сообщений (MPI / PVM) можно рассматривать как взаимодополняющие и иногда использовались вместе, например, на серверах с несколькими большими узлами с общей памятью.
Общая языковая инфраструктура
Двумя управляемыми реализациями .NET Common Language Infrastructure являются Pure Mpi.NET и MPI.NET, исследовательская работа в Университете Индианы под лицензией в стиле BSD .
Он совместим с Mono и может в полной мере использовать базовые сетевые структуры MPI с низкой задержкой.
Общие процедуры mpi
int MPI_Init( int* argc, char*** argv)
MPI_Init – инициализация параллельной части приложения. Реальная
инициализация для каждого приложения выполняется не более одного раза,
а если MPI уже был инициализирован, то никакие действия не выполняются
и происходит немедленный возврат из подпрограммы. Все оставшиеся MPI-процедуры
могут быть вызваны только после вызова MPI_Init.
Возвращает: в случае успешного выполнения – MPI_SUCCESS, иначе
– код ошибки. (То же самое возвращают и все остальные функции, рассматриваемые
в данном руководстве.)
Объединение запросов на взаимодействие
Процедуры данной группы позволяют снизить накладные расходы, возникающие
в рамках одного процессора при обработке приема/передачи и перемещении
необходимой информации между процессом и сетевым контроллером. Несколько
запросов на прием и/или передачу могут объединяться вместе для того, чтобы
далее их можно было бы запустить одной командой.
int MPI_Send_init(
void *buf, int count, MPI_Datatype datatype, int dest,
int msgtag, MPI_Comm comm, MPI_Request *request)
- buf – адрес начала буфера посылки сообщения
- count – число передаваемых элементов в сообщении
- datatype – тип передаваемых элементов
- dest – номер процесса-получателя
- msgtag – идентификатор сообщения
- comm – идентификатор группы
- OUT request – идентификатор асинхронной передачи
Формирование запроса на выполнение пересылки данных. Все параметры точно
такие же, как и у подпрограммы MPI_Isend, однако в отличие от нее
пересылка не начинается до вызова подпрограммы MPI_Startall.
Официальные реализации
Многие другие разработки являются производными от MPICH, LAM и других разработок, включая, помимо прочего, коммерческие реализации от HP , Intel , Microsoft и NEC .
Хотя спецификации требуют наличия интерфейса C и Fortran, язык, используемый для реализации MPI, не ограничивается соответствием языку или языкам, которые он стремится поддерживать во время выполнения. Большинство реализаций объединяют C, C и язык ассемблера и предназначены для программистов на C, C и Fortran.
В ABI из MPI реализаций грубо разделены между MPICH и OpenMP производных, так что библиотека из одной семьи работает как капля в замене одного из того же семейства, но прямая замена всей семьи невозможно. Французский CEA поддерживает интерфейс оболочки для облегчения таких переключений.
Предопределенные константы типа элементов сообщений
Константы MPI | Тип в C |
MPI_CHAR | signed char |
MPI_SHORT | signed int |
MPI_INT | signed int |
MPI_LONG | signed long int |
MPI_UNSIGNED_CHAR | unsigned char |
MPI_UNSIGNED_SHORT | unsigned int |
MPI_UNSIGNED | unsigned int |
MPI_UNSIGNED_LONG | unsigned long int |
MPI_FLOAT | float |
MPI_DOUBLE | double |
MPI_LONG_DOUBLE | long double |
Прием/передача сообщений без блокировки
int MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dest,
int msgtag, MPI_Comm comm, MPI_Request *request)
- buf – адрес начала буфера посылки сообщения
- count – число передаваемых элементов в сообщении
- datatype – тип передаваемых элементов
- dest – номер процесса-получателя
- msgtag – идентификатор сообщения
- comm – идентификатор группы
- OUT request – идентификатор асинхронной передачи
Передача сообщения, аналогичная MPI_Send, однако возврат из подпрограммы
происходит сразу после инициализации процесса передачи без ожидания обработки
всего сообщения, находящегося в буфере buf. Это означает, что нельзя
повторно использовать данный буфер для других целей без получения дополнительной
информации о завершении данной посылки.
Окончание процесса передачи (т.е.
того момента, когда можно переиспользовать буфер buf без опасения
испортить передаваемое сообщение) можно определить с помощью параметра
request и процедур MPI_Wait и MPI_Test.
Прием/передача сообщений с блокировкой
int MPI_Send(void* buf, int count, MPI_Datatype datatype, int dest,
int msgtag, MPI_Comm comm)
- buf – адрес начала буфера посылки сообщения
- count – число передаваемых элементов в сообщении
- datatype – тип передаваемых элементов
- dest – номер процесса-получателя
- msgtag – идентификатор сообщения
- comm – идентификатор группы
Блокирующая посылка сообщения с идентификатором msgtag, состоящего
из count элементов типа datatype, процессу с номером dest.
Все элементы сообщения расположены подряд в буфере buf. Значение
count может быть нулем.
Блокировка гарантирует корректность повторного использования всех параметров
после возврата из подпрограммы. Выбор способа осуществления этой гарантии:
копирование в промежуточный буфер или непосредственная передача процессу
dest, остается за MPI.
Следует специально отметить, что возврат
из подпрограммы MPI_Send не означает ни того, что сообщение уже
передано процессу dest, ни того, что сообщение покинуло процессорный
элемент, на котором выполняется процесс, выполнивший MPI_Send.
Пример программы
Вот и “Привет, мир!” программа на MPI, написанная на C. В этом примере мы отправляем приветственное сообщение каждому процессору, тривиально обрабатываем его, возвращаем результаты основному процессу и распечатываем сообщения.
/* "Hello World" MPI Test Program*/#include<assert.h>#include<stdio.h>#include<string.h>#include<mpi.h>intmain(intargc,char**argv){charbuf[256];intmy_rank,num_procs;/* Initialize the infrastructure necessary for communication */MPI_Init(&argc,&argv);/* Identify this process */MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);/* Find out how many total processes are active */MPI_Comm_size(MPI_COMM_WORLD,&num_procs);/* Until this point, all programs have been doing exactly the same. Here, we check the rank to distinguish the roles of the programs */if(my_rank==0){intother_rank;printf("We have %i processes.n",num_procs);/* Send messages to all other processes */for(other_rank=1;other_rank<num_procs;other_rank ){sprintf(buf,"Hello %i!",other_rank);MPI_Send(buf,sizeof(buf),MPI_CHAR,other_rank,0,MPI_COMM_WORLD);}/* Receive messages from all other process */for(other_rank=1;other_rank<num_procs;other_rank ){MPI_Recv(buf,sizeof(buf),MPI_CHAR,other_rank,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);printf("%sn",buf);}}else{/* Receive message from process #0 */MPI_Recv(buf,sizeof(buf),MPI_CHAR,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);assert(memcmp(buf,"Hello ",6)==0);/* Send message to process #0 */sprintf(buf,"Process %i reporting for duty.",my_rank);MPI_Send(buf,sizeof(buf),MPI_CHAR,0,0,MPI_COMM_WORLD);}/* Tear down the communication infrastructure */MPI_Finalize();return0;}
При запуске с 4 процессами он должен выдать следующий результат:
$ mpicc example.c && mpiexec -n 4 ./a.out We have 4 processes. Process 1 reporting for duty. Process 2 reporting for duty. Process 3 reporting for duty.
Вот mpiexecкоманда, используемая для выполнения примера программы с 4 процессами , каждый из которых является независимым экземпляром программы во время выполнения и имеет присвоенные ранги (т.е. числовые идентификаторы) 0, 1, 2 и 3.
Тем самым упрощается, но не требуется, модель программирования « одна программа – несколько данных» ( SPMD ); многие реализации MPI позволяют запускать несколько разных исполняемых файлов в одном задании MPI.
У каждого процесса есть свой ранг, общее количество процессов в мире и возможность общаться между ними либо с помощью двухточечной связи (отправка / получение), либо посредством коллективного взаимодействия между группой. Для MPI достаточно предоставить программе в стиле SPMD MPI_COMM_WORLDсвой ранг и размер мира, чтобы алгоритмы могли решать, что им делать.
В более реалистичных ситуациях управление вводом-выводом осуществляется более тщательно, чем в этом примере. MPI не определяет, как стандартный ввод-вывод (stdin, stdout, stderr) должен работать в данной системе. Обычно он работает должным образом в процессе ранга 0, а некоторые реализации также захватывают и направляют выходные данные других процессов.
MPI использует понятие процесса, а не процессора. Копии программ отображаются на процессоры средой выполнения MPI . В этом смысле параллельная машина может отображаться на один физический процессор или на N процессоров, где N – количество доступных процессоров, или даже что-то среднее между ними.
Для максимального параллельного ускорения используется больше физических процессоров. Этот пример подстраивает свое поведение к размеру мира N , поэтому он также стремится масштабироваться до конфигурации среды выполнения без компиляции для каждого варианта размера, хотя решения во время выполнения могут варьироваться в зависимости от этого абсолютного количества доступного параллелизма.
Принятие mpi-2
Принятие MPI-1.2 было универсальным, особенно в кластерных вычислениях, но принятие MPI-2.1 было более ограниченным. Проблемы включают:
- Реализации MPI-2 включают ввод-вывод и динамическое управление процессами, а размер промежуточного программного обеспечения значительно больше. Большинство сайтов, использующих системы пакетного планирования, не могут поддерживать динамическое управление процессами. Параллельный ввод / вывод MPI-2 хорошо принят.
- Многие программы MPI-1.2 были разработаны до MPI-2. Изначально проблемы переносимости замедлили внедрение, хотя более широкая поддержка уменьшила это.
- Многие приложения MPI-1.2 используют только подмножество этого стандарта (16-25 функций) без реальной потребности в функциональности MPI-2.
Производные типы данных
Многие функции MPI требуют, чтобы вы указали тип данных, которые пересылаются между процессами. Это связано с тем, что MPI нацелен на поддержку гетерогенных сред, в которых типы могут быть представлены по-разному на разных узлах (например, они могут работать с разными архитектурами ЦП с разным порядком байтов ), и в этом случае реализации MPI могут выполнять преобразование данных .
Вот пример на C, который передает массивы ints от всех процессов одному. Один принимающий процесс называется «корневым» процессом, и это может быть любой назначенный процесс, но обычно это будет процесс 0. Все процессы запрашивают отправку своих массивов в корень с помощью MPI_Gather, что эквивалентно наличию каждого процесса (включая root сам)
intsend_array[100];introot=0;/* or whatever */intnum_procs,*recv_array;MPI_Comm_size(comm,&num_procs);recv_array=malloc(num_procs*sizeof(send_array));MPI_Gather(send_array,sizeof(send_array)/sizeof(*send_array),MPI_INT,recv_array,sizeof(send_array)/sizeof(*send_array),MPI_INT,root,comm);
Однако вы можете вместо этого отправлять данные одним блоком, а не 100 intс. Для этого определите производный тип данных «непрерывный блок»:
MPI_Datatypenewtype;MPI_Type_contiguous(100,MPI_INT,&newtype);MPI_Type_commit(&newtype);MPI_Gather(array,1,newtype,receive_array,1,newtype,root,comm);
Для передачи класса или структуры данных MPI_Type_create_structсоздает тип MPI_predefinedданных, производный от MPI, из типов данных, как показано ниже:
куда:
disp(Смещения) массив необходим для выравнивания структуры данных , так как компилятор может колодки переменных в классе или структуру данных. Самый безопасный способ найти расстояние между разными полями – получить их адреса в памяти.
Передача структуры данных в виде одного блока значительно быстрее, чем передача одного элемента за раз, особенно если операция должна быть повторена. Это связано с тем, что блоки фиксированного размера не требуют сериализации во время передачи.
Учитывая следующие структуры данных:
Вот код C для создания типа данных, производного от MPI:
staticconstintblocklen[]={1,1,1,1};staticconstMPI_Aintdisp[]={offsetof(structB,a) offsetof(structA,f),offsetof(structB,a) offsetof(structA,p),offsetof(structB,pp),offsetof(structB,vp)};staticMPI_Datatypetype[]={MPI_INT,MPI_SHORT,MPI_INT,MPI_INT};MPI_Datatypenewtype;MPI_Type_create_struct(sizeof(type)/sizeof(*type),blocklen,disp,type,&newtype);MPI_Type_commit(&newtype);
Работа с группами процессов
int MPI_Comm_split( MPI_Comm comm,
int color, int key, MPI_Comm *newcomm)
- comm – идентификатор группы
- color – признак разделения на группы
- key – параметр, определяющий нумерацию в новых группах
- OUT newcomm – идентификатор новой группы
Данная процедура разбивает все множество процессов, входящих в группу
comm, на непересекающиеся подгруппы – одну подгруппу на каждое значение
параметра color (неотрицательное число). Каждая новая подгруппа
содержит все процессы одного цвета.
Синхронизация процессов
int MPI_Barrier( MPI_Comm comm)
- comm – идентификатор группы
Блокирует работу процессов, вызвавших данную процедуру, до тех пор,
пока все оставшиеся процессы группы comm также не выполнят эту процедуру.
Совмещенные прием/передача сообщений
int MPI_Sendrecv(
void *sbuf, int scount, MPI_Datatype stype,
int dest, int stag, void *rbuf, int rcount,
MPI_Datatype rtype, int source, MPI_Datatype rtag,
MPI_Comm comm, MPI_Status *status)
- sbuf – адрес начала буфера посылки сообщения
- scount – число передаваемых элементов в сообщении
- stype – тип передаваемых элементов
- dest – номер процесса-получателя
- stag – идентификатор посылаемого сообщения
- OUT rbuf – адрес начала буфера приема сообщения
- rcount – число принимаемых элементов сообщения
- rtype – тип принимаемых элементов
- source – номер процесса-отправителя
- rtag – идентификатор принимаемого сообщения
- comm – идентификатор группы
- OUT status – параметры принятого сообщения
Данная операция объединяет в едином запросе посылку и прием сообщений.
Принимающий и отправляющий процессы могут являться одним и тем же процессом.
Сообщение, отправленное операцией MPI_Sendrecv, может быть принято
обычным образом, и точно также операция MPI_Sendrecv может принять
сообщение, отправленное обычной операцией MPI_Send. Буфера приема
и посылки обязательно должны быть различными.
Сравнение с pvm.
PVM – это изначально исследовательский проект. Его несомненными достоинствами являются простота использования ( в теории ) и почтенный возраст – он появился на свет в 1989 году, и, таким образом, на 6 лет старше MPI.
Надо признать, по сравнению с PVM, MPI – это СЛОЖНЫЙ пакет. То, что в PVM реализовано одним-единственным способом, в MPI может быть сделано несколькими, про которые говорится: способ А прост в использовании, но не очень эффективен; способ Б сложнее, но эффективнее;
а способ В сложнее и эффективнее при определенных условиях. Изложение в доступных через Интернет учебниках расчитано на профессиональных программистов, а не на прикладников, потому что упорядочено по областям применения (способы А, Б и В в одной главе), а не по уровням сложности (способ А в первой главе, способ Б в следующей, способ В и вовсе вынесен в приложения).
Ergo, главным недостатком MPI являетсяотсутствие ПРАВИЛЬНО упорядоченного описаниядля непрофессионалов.
Судите сами, насколько это утверждение применимо к пособию, которое сейчас перед Вами.
Сравнение с низкоуровневыми пересылками.
Часто приходится слышать утверждение, что низкоуровневые пересылки через разделяемую память и семафоры предпочтительнее применения таких библиотек как MPI, потому что работают быстрее. Против такой точки зрения существует 4 очень веских довода:
- В хорошо распараллеленном приложении на собственно взаимодействие между ветвями (пересылки данных и синхронизацию) тратится небольшая доля времени – несколько процентов от общего времени работы. Таким образом, замедление пересылок, допустим, в два раза не означает общего падения производительности вдвое – она понизится на несколько процентов. Зачастую такое понижение производительности является приемлемым и с лихвой оправдывается прочими соображениями ;
- MPI – это изначально БЫСТРЫЙ инструмент. Для повышения скорости в нем используются приемы, о которых прикладные программисты зачастую просто не задумываются. Например:
И все-все скурпулезно отлажено и протестировано!
- Перенос – отныне не требует переписывания и повторной отладки. Незаменимое качество для программы, которой предстоит пользоваться широкому кругу людей. Следует учитывать и то обстоятельство, что УЖЕ появляются машины, на которых из средств межпрограммного взаимодействия есть только MPI – и ничего более.
- ОТЛАДКА – ей посвящена оставшаяся часть раздела.
Перечисление, иллюстрации и способы избежания типовых ошибок, допускаемых при параллельном программировании – тема отдельного трактата. Сразу следует оговориться, что панацеи от них пока не придумано – иначе о таковой тотчас стало бы общеизвестно. MPI ни от одной из типовых ошибок (кроме “нарушения ордера”) не страхует – но он уменьшает вероятность их совершить!
Функции работы с разделяемой памятью и с семафорами слишком атомарны, примитивны. Вероятность без ошибки реализовать с их помощью нужное программе действие стремительно уменьшается с ростом количества инструкций ; вероятность найти ошибку путем отладки близка к нулю, потому что отладочное средство привносит задержку в выполнение одних ветвей, и тем самым позволяет нормально работать другим (ветви перестают конкурировать за совместно используемые данные).
Функциональность
Интерфейс MPI предназначен для обеспечения необходимой виртуальной топологии, синхронизации и функциональности связи между набором процессов (которые были сопоставлены с узлами / серверами / экземплярами компьютеров) независимым от языка способом, с синтаксисом, зависящим от языка (привязки), плюс несколько языковых функций.
Программы MPI всегда работают с процессами, но программисты обычно называют процессы процессорами. Обычно для максимальной производительности каждому процессору (или ядру в многоядерной машине) назначается только один процесс.
Функции библиотеки MPI включают в себя, но не ограничиваются ими, точка-точка сближения типа передачи / приема операции, выбирая между декартовой или графа -подобных логической топологии процесса, обмен данными между парами процессов (отправка / прием операций), сочетающий в себе частичное результаты вычислений (операции сбора и сокращения), синхронизации узлов (барьерная операция), а также получение сетевой информации, такой как количество процессов в вычислительном сеансе, текущий идентификатор процессора, которому сопоставлен процесс, соседние процессы, доступные в логическая топология и так далее.
Операции «точка-точка» бывают синхронными , асинхронными , буферизованными и готовыми , чтобы обеспечить как относительно более сильную, так и более слабую семантику для аспектов синхронизации при рандеву-отправке. Многие выдающиеся операции возможны в асинхронном режиме в большинстве реализаций.
MPI-1 и MPI-2 позволяют реализации, которые перекрывают обмен данными и вычисления, но практика и теория различаются. MPI также определяет Потокобезопасную интерфейсы, которые имеют сцепление и сцепные стратегии , которые помогут избежать скрытых состояний в интерфейсе.
Языковые привязки
Привязки – это библиотеки, которые расширяют поддержку MPI на другие языки путем обертывания существующей реализации MPI, такой как MPICH или Open MPI.
Ввод / вывод
Функция параллельного ввода / вывода иногда называется MPI-IO и относится к набору функций, предназначенных для абстрагирования управления вводом / выводом в распределенных системах в MPI и обеспечения легкого доступа к файлам шаблонным способом с использованием существующих функций производных типов данных. .
Небольшое исследование, проведенное по этой функции, показывает, что получение высокого прироста производительности с помощью MPI-IO может оказаться нетривиальным. Например, реализация умножения разреженной матрицы на вектор с использованием библиотеки ввода-вывода MPI демонстрирует общее поведение с незначительным приростом производительности, но эти результаты неубедительны.
Только после того, как идея коллективного ввода-вывода была реализована в MPI-IO, MPI-IO начал получать широкое распространение. Коллективный ввод-вывод существенно увеличивает пропускную способность ввода-вывода приложений за счет того, что процессы коллективно преобразуют небольшие и несмежные операции ввода-вывода в большие и непрерывные операции, тем самым уменьшая накладные расходы на блокировку и поиск диска.
Благодаря огромным преимуществам в производительности MPI-IO также стал базовым уровнем ввода-вывода для многих современных библиотек ввода-вывода, таких как HDF5 и Parallel NetCDF . Его популярность также подтолкнула к исследованиям по оптимизации коллективного ввода-вывода, таким как ввод-вывод с учетом макета и межфайловая агрегация.