stringtranslate.com

Интерфейс передачи сообщений

Интерфейс передачи сообщений ( MPI ) — это стандартизированный и переносимый стандарт передачи сообщений , разработанный для работы на параллельных вычислительных архитектурах . [1] Стандарт MPI определяет синтаксис и семантику библиотечных процедур , которые полезны широкому кругу пользователей, пишущих переносимые программы передачи сообщений на C , C++ и Fortran . Существует несколько реализаций MPI с открытым исходным кодом , которые способствовали развитию индустрии параллельного программного обеспечения и поощряли разработку переносимых и масштабируемых крупномасштабных параллельных приложений.

История

Работа над интерфейсом передачи сообщений началась летом 1991 года, когда небольшая группа исследователей начала обсуждения в горном убежище в Австрии. Из этого обсуждения вышло Семинар по стандартам передачи сообщений в среде распределенной памяти, который состоялся 29–30 апреля 1992 года в Уильямсбурге, штат Вирджиния . [2] Участники Уильямсбурга обсудили основные функции, необходимые для стандартного интерфейса передачи сообщений, и создали рабочую группу для продолжения процесса стандартизации. Джек Донгарра , Тони Хей и Дэвид У. Уокер выдвинули предварительный проект предложения «MPI1» в ноябре 1992 года. В ноябре 1992 года в Миннеаполисе состоялось заседание рабочей группы MPI, на котором было принято решение о переводе процесса стандартизации на более формальную основу. Рабочая группа MPI встречалась каждые 6 недель в течение первых 9 месяцев 1993 года. Проект стандарта MPI был представлен на конференции Supercomputing '93 в ноябре 1993 года. [3] После периода публичных комментариев, которые привели к некоторым изменениям в MPI, версия 1.0 MPI была выпущена в июне 1994 года. Эти встречи и обсуждения по электронной почте вместе составили Форум MPI, членство в котором открыто для всех членов сообщества высокопроизводительных вычислений .

В работе над MPI участвовало около 80 человек из 40 организаций, в основном из США и Европы. Большинство основных поставщиков параллельных компьютеров были вовлечены в работу над MPI, сотрудничая с исследователями из университетов, правительственных лабораторий и промышленности .

MPI предоставляет поставщикам параллельного оборудования четко определенный базовый набор процедур, которые могут быть эффективно реализованы. В результате поставщики оборудования могут опираться на этот набор стандартных низкоуровневых процедур для создания высокоуровневых процедур для среды связи с распределенной памятью, поставляемой с их параллельными машинами . MPI предоставляет простой в использовании переносимый интерфейс для базового пользователя, но при этом достаточно мощный, чтобы позволить программистам использовать высокопроизводительные операции передачи сообщений, доступные на продвинутых машинах.

В попытке создать универсальный стандарт для передачи сообщений исследователи не основывали его на одной системе, а включили в него наиболее полезные функции нескольких систем, включая разработанные IBM, Intel , nCUBE , PVM, Express, P4 и PARMACS. Парадигма передачи сообщений привлекательна из-за широкой переносимости и может использоваться в коммуникации для многопроцессорных систем с распределенной и общей памятью, сетей рабочих станций и комбинации этих элементов. Парадигма может применяться в различных настройках, независимо от скорости сети или архитектуры памяти.

Поддержка встреч MPI частично осуществлялась DARPA и Национальным научным фондом США (NSF) в рамках гранта ASC-9310330, NSF Science and Technology Center Cooperative Agreement number CCR-8809615, а также Европейской комиссией через проект Esprit P6643. Университет Теннесси также внес финансовый вклад в форум MPI.

Обзор

MPI — это протокол связи для программирования [4] параллельных компьютеров . Поддерживаются как двухточечная, так и коллективная связь. MPI — это «интерфейс прикладного программирования для передачи сообщений, вместе с протокольными и семантическими спецификациями того, как его функции должны вести себя в любой реализации». [5] Цели MPI — высокая производительность, масштабируемость и переносимость. MPI остается доминирующей моделью, используемой в высокопроизводительных вычислениях сегодня. [6]

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

Основная модель MPI-1 не имеет концепции общей памяти , а MPI-2 имеет только ограниченную концепцию распределенной общей памяти . Тем не менее, программы MPI регулярно запускаются на компьютерах с общей памятью, и как MPICH , так и Open MPI могут использовать общую память для передачи сообщений, если она доступна. [7] [8] Разработка программ вокруг модели MPI (в отличие от явных моделей общей памяти ) имеет преимущества при запуске на архитектурах NUMA, поскольку MPI поощряет локальность памяти . Явное программирование общей памяти было введено в MPI-3. [9] [10] [11]

Хотя MPI относится к уровням 5 и выше эталонной модели OSI , реализации могут охватывать большинство уровней, при этом сокеты и протокол управления передачей (TCP) используются на транспортном уровне.

Большинство реализаций MPI состоят из определенного набора процедур, напрямую вызываемых из C , C++ , Fortran (т. е. API) и любого языка, способного взаимодействовать с такими библиотеками, включая C# , Java или Python . Преимущества MPI по сравнению со старыми библиотеками передачи сообщений заключаются в переносимости (поскольку MPI был реализован почти для каждой архитектуры распределенной памяти) и скорости (поскольку каждая реализация в принципе оптимизирована для оборудования, на котором она работает).

MPI использует Language Independent Specifications (LIS) для вызовов и языковых привязок. Первый стандарт MPI специфицировал привязки ANSI C и Fortran-77 вместе с LIS. Проект был представлен на Supercomputing 1994 (ноябрь 1994) [12] и вскоре после этого был окончательно доработан. Около 128 функций составляют стандарт MPI-1.3, который был выпущен как финальный вариант серии MPI-1 в 2008 году. [13]

В настоящее время стандарт имеет несколько версий: версия 1.3 (обычно сокращенно MPI-1 ), которая делает акцент на передаче сообщений и имеет статическую среду выполнения, MPI-2.2 (MPI-2), которая включает новые функции, такие как параллельный ввод-вывод, динамическое управление процессами и удаленные операции с памятью, [14] и MPI-3.1 (MPI-3), которая включает расширения коллективных операций с неблокируемыми версиями и расширения односторонних операций. [15] 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) можно считать взаимодополняющими и иногда использовались вместе, например, на серверах с несколькими большими узлами общей памяти.

Функциональность

Интерфейс MPI предназначен для предоставления необходимой виртуальной топологии, синхронизации и функциональности связи между набором процессов (которые были сопоставлены с узлами/серверами/экземплярами компьютеров) независимым от языка способом, с синтаксисом, специфичным для языка (привязками), а также несколькими специфичными для языка функциями. Программы MPI всегда работают с процессами, но программисты обычно называют процессы процессорами. Обычно для максимальной производительности каждому ЦП (или ядру в многоядерной машине) назначается только один процесс. Это назначение происходит во время выполнения через агента, который запускает программу MPI, обычно называемую mpirun или mpiexec.

Функции библиотеки MPI включают в себя, помимо прочего, операции отправки/приема типа «точка-точка», выбор между декартовой или графоподобной топологией логического процесса, обмен данными между парами процессов (операции отправки/приема), объединение частичных результатов вычислений (операции сбора и редукции), синхронизацию узлов (барьерная операция), а также получение сетевой информации, такой как количество процессов в сеансе вычислений, текущая идентификация процессора, с которым сопоставлен процесс, соседние процессы, доступные в логической топологии, и т. д. Операции «точка-точка» бывают синхронными , асинхронными , буферизованными и готовыми , что позволяет использовать как относительно более сильную, так и более слабую семантику для аспектов синхронизации при отправке-свидании. Многие выдающиеся [ требуется разъяснение ] операции возможны в асинхронном режиме в большинстве реализаций.

MPI-1 и MPI-2 позволяют реализовать перекрывающиеся коммуникации и вычисления, но практика и теория различаются. MPI также определяет потокобезопасные интерфейсы, которые имеют стратегии связности и сопряжения , помогающие избегать скрытого состояния в интерфейсе. Относительно легко написать многопоточный код MPI точка-точка, и некоторые реализации поддерживают такой код. Многопоточная коллективная коммуникация лучше всего достигается с несколькими копиями коммуникаторов, как описано ниже.

Концепции

MPI предоставляет несколько функций. Следующие концепции предоставляют контекст для всех этих возможностей и помогают программисту решить, какую функциональность использовать в своих прикладных программах. Четыре из восьми основных концепций MPI являются уникальными для MPI-2.

Коммуникатор

Объекты коммуникатора соединяют группы процессов в сеансе MPI. Каждый коммуникатор присваивает каждому содержащемуся процессу независимый идентификатор и упорядочивает содержащиеся в нем процессы в упорядоченной топологии . MPI также имеет явные группы, но они в основном хороши для организации и реорганизации групп процессов перед созданием другого коммуникатора. MPI понимает операции внутри коммуникатора одной группы и двустороннюю связь между коммуникаторами. В MPI-1 наиболее распространены операции внутри группы. Двусторонние операции в основном появляются в MPI-2, где они включают коллективную связь и динамическое управление внутри процесса.

Коммуникаторы могут быть разделены с помощью нескольких команд MPI. Эти команды включают MPI_COMM_SPLIT, где каждый процесс присоединяется к одному из нескольких цветных подкоммуникаторов, объявляя себя имеющим этот цвет.

Основы двухточечного соединения

Ряд важных функций MPI включают коммуникацию между двумя определенными процессами. Популярным примером является MPI_Send, которая позволяет одному указанному процессу отправлять сообщение второму указанному процессу. Операции точка-точка, как их называют, особенно полезны в шаблонной или нерегулярной коммуникации, например, в архитектуре параллельных данных , в которой каждый процессор регулярно обменивается областями данных с определенными другими процессорами между шагами вычислений, или в архитектуре ведущий-ведомый , в которой ведущий отправляет новые данные задачи ведомому всякий раз, когда предыдущая задача завершена.

MPI-1 определяет механизмы как блокирующих , так и неблокирующих механизмов связи «точка-точка», а также так называемый механизм «готовой отправки», при котором запрос на отправку может быть сделан только после того, как уже сделан соответствующий запрос на получение.

Коллективные основы

Коллективные функции включают в себя связь между всеми процессами в группе процессов (что может означать весь пул процессов или определенное программой подмножество). Типичная функция — вызов MPI_Bcast(сокращение от « broadcast »). Эта функция берет данные из одного узла и отправляет их всем процессам в группе процессов. Обратная операция — это MPI_Reduceвызов, который берет данные из всех процессов в группе, выполняет операцию (например, суммирование) и сохраняет результаты на одном узле. MPI_Reduceчасто бывает полезно в начале или конце большого распределенного вычисления, где каждый процессор работает с частью данных, а затем объединяет их в результат.

Другие операции выполняют более сложные задачи, например, MPI_Alltoallпереупорядочивают n элементов данных таким образом, что n-й узел получает n -й элемент данных из каждого.

Производные типы данных

Многие функции MPI требуют указания типа данных, которые передаются между процессами. Это связано с тем, что MPI нацелен на поддержку гетерогенных сред, где типы могут быть представлены по-разному на разных узлах [16] (например, они могут работать на разных архитектурах ЦП с разным порядком байтов ), в этом случае реализации MPI могут выполнять преобразование данных . [16] Поскольку язык C не позволяет передавать сам тип в качестве параметра, MPI предопределяет константы MPI_INT, MPI_CHAR, MPI_DOUBLEдля соответствия int, char, doubleи т. д.

Вот пример на языке C, который передает массивы ints из всех процессов в один. Один принимающий процесс называется «корневым» процессом, и это может быть любой назначенный процесс, но обычно это будет процесс 0. Все процессы запрашивают отправку своих массивов в корень с помощью MPI_Gather, что эквивалентно вызову каждым процессом (включая сам корень) MPI_Sendи выполнению корнем соответствующего количества упорядоченных MPI_Recvвызовов для сборки всех этих массивов в один больший: [17]

int send_array [ 100 ]; int root = 0 ; /* или что-то еще */ int num_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Для этого определите производный тип данных "contiguous block":

MPI_Datatype новый тип ; MPI_Type_contiguous ( 100 , MPI_INT , & новый тип ); MPI_Type_commit ( & новый тип ); MPI_Gather ( массив , 1 , новый тип , receive_array , 1 , новый тип , root , comm );          

Для передачи класса или структуры данных MPI_Type_create_structсоздает производный тип данных MPI из MPI_predefinedтипов данных следующим образом:

int MPI_Type_create_struct ( int count , int * blocklen , MPI_Aint * disp , MPI_Datatype * type , MPI_Datatype * newtype )          

где:

Массив disp(смещений) необходим для выравнивания структуры данных , поскольку компилятор может дополнять переменные в классе или структуре данных. Самый безопасный способ найти расстояние между различными полями — получить их адреса в памяти. Это делается с помощью MPI_Get_address, что обычно совпадает с &оператором C, но это может быть неверно при работе с сегментацией памяти . [18]

Передача структуры данных как одного блока значительно быстрее, чем передача одного элемента за раз, особенно если операция должна повторяться. Это связано с тем, что блоки фиксированного размера не требуют сериализации во время передачи. [19]

Имеются следующие структуры данных:

структура A { int f ; short p ; };      структура B { структура A a ; int pp , vp ; };        

Вот код на языке C для создания типа данных, производного от MPI:

static const int blocklen [] = { 1 , 1 , 1 , 1 }; static const MPI_Aint disp [] = { offsetof ( struct B , a ) + offsetof ( struct A , f ), offsetof ( struct B , a ) + offsetof ( struct A , p ), offsetof ( struct B , pp ), offsetof ( struct B , vp ) }; static MPI_Datatype type [] = { MPI_INT , MPI_SHORT , MPI_INT , MPI_INT }; MPI_Datatype newtype ; MPI_Type_create_struct ( sizeof ( type ) / sizeof ( * type ), blocklen , disp , type , & newtype ); MPI_Type_commit ( & newtype );                                               

Концепции MPI-2

Односторонняя коммуникация

MPI-2 определяет три односторонние операции связи, MPI_Put, MPI_Getи MPI_Accumulate, которые являются записью в удаленную память, чтением из удаленной памяти и операцией редукции в той же памяти в ряде задач соответственно. Также определены три различных метода синхронизации этой связи (глобальная, парная и удаленная блокировки), поскольку спецификация не гарантирует, что эти операции будут выполнены до точки синхронизации.

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

Динамическое управление процессами

Ключевым аспектом является «способность процесса 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интракоммуникатор, но может взаимодействовать с родителем и интеркоммуникатором, который возвращает функция. MPI_Comm_spawn_multiple— это альтернативный интерфейс, который позволяет различным порожденным экземплярам быть разными двоичными файлами с разными аргументами. [20]

Ввод/вывод

Функция параллельного ввода-вывода иногда называется MPI-IO [21] и относится к набору функций, предназначенных для абстрагирования управления вводом-выводом в распределенных системах до MPI, а также позволяет легко получать доступ к файлам шаблонным способом с использованием существующих функциональных возможностей производных типов данных.

Небольшое исследование, проведенное по этой функции, показывает, что получение высокого прироста производительности с помощью MPI-IO может быть нетривиальным. Например, реализация умножения разреженной матрицы на вектор с использованием библиотеки ввода-вывода MPI показывает общее поведение незначительного прироста производительности, но эти результаты не являются окончательными. [22] Только после того, как идея коллективного ввода-вывода [23] была реализована в MPI-IO, MPI-IO начал получать широкое распространение. Коллективный ввод-вывод существенно увеличивает пропускную способность ввода-вывода приложений, заставляя процессы коллективно преобразовывать небольшие и несмежные операции ввода-вывода в большие и непрерывные, тем самым уменьшая накладные расходы на блокировку и поиск на диске. Благодаря своим огромным преимуществам в производительности MPI-IO также стал базовым уровнем ввода-вывода для многих современных библиотек ввода-вывода, таких как HDF5 и Parallel NetCDF . Его популярность также побудила к исследованиям по коллективной оптимизации ввода-вывода, такой как ввод-вывод с учетом компоновки [24] и агрегация между файлами. [25] [26]

Официальные реализации

Многие другие разработки являются производными от MPICH, LAM и других работ, включая, помимо прочего, коммерческие реализации от HPE , Intel , Microsoft и NEC .

Хотя спецификации предписывают интерфейс C и Fortran, язык, используемый для реализации MPI, не ограничен соответствием языку или языкам, которые он стремится поддерживать во время выполнения. Большинство реализаций объединяют языки C, C++ и ассемблера и нацелены на программистов C, C++ и Fortran. Привязки доступны для многих других языков, включая Perl, Python, R, Ruby, Java и CL (см. #Привязки к языкам).

ABI реализаций MPI примерно разделены между производными MPICH и Open MPI , так что библиотека из одного семейства работает как замена библиотеки из того же семейства, но прямая замена между семействами невозможна. Французский CEA поддерживает интерфейс-оболочку для облегчения таких переключений. [27]

Аппаратное обеспечение

Исследования аппаратного обеспечения MPI сосредоточены на реализации MPI непосредственно в оборудовании, например, через процессор-в-памяти , встраивая операции MPI в микросхемы чипов RAM в каждом узле. Подразумевается, что этот подход не зависит от языка, операционной системы и ЦП, но не может быть легко обновлен или удален.

Другой подход заключался в добавлении аппаратного ускорения к одной или нескольким частям операции, включая аппаратную обработку очередей MPI и использование RDMA для прямой передачи данных между памятью и контроллером сетевого интерфейса без вмешательства ЦП или ядра ОС.

Обертки компилятора

mpicc (и аналогично mpic++ , mpif90 и т. д.) — это программа, которая оборачивает существующий компилятор, чтобы установить необходимые флаги командной строки при компиляции кода, использующего MPI. Обычно она добавляет несколько флагов, которые позволяют коду быть скомпилированным и скомпонованным с библиотекой MPI. [28]

Языковые привязки

Привязки — это библиотеки, которые расширяют поддержку MPI на другие языки, создавая оболочку для существующей реализации MPI, такой как MPICH или Open MPI.

Общая языковая инфраструктура

Две управляемые реализации Common Language Infrastructure .NET — это Pure Mpi.NET [29] и MPI.NET, [30] исследовательская работа в Университете Индианы, лицензированная по лицензии BSD . Она совместима с Mono и может в полной мере использовать базовые сетевые структуры MPI с низкой задержкой.

Ява

Хотя Java не имеет официальной привязки MPI, несколько групп пытаются объединить эти два подхода с разной степенью успеха и совместимости. Одной из первых попыток была mpiJava Брайана Карпентера [31] , по сути, набор оболочек Java Native Interface (JNI) для локальной библиотеки C MPI, что приводит к гибридной реализации с ограниченной переносимостью, которая также должна быть скомпилирована с использованием конкретной используемой библиотеки MPI.

Однако этот оригинальный проект также определил mpiJava API [32] ( де-факто MPI API для Java, который тесно следовал эквивалентным привязкам C++), который переняли другие последующие проекты Java MPI. Одним из менее используемых API является MPJ API, который был разработан, чтобы быть более объектно-ориентированным и ближе к соглашениям о кодировании Sun Microsystems . [33] Помимо API, библиотеки Java MPI могут либо зависеть от локальной библиотеки MPI, либо реализовывать функции передачи сообщений в Java, в то время как некоторые, такие как P2P-MPI, также предоставляют функциональность одноранговой связи и допускают работу на смешанных платформах.

Некоторые из наиболее сложных частей Java/MPI возникают из-за характеристик Java, таких как отсутствие явных указателей и линейное адресное пространство памяти для его объектов, что делает передачу многомерных массивов и сложных объектов неэффективной. Обходные пути обычно включают передачу одной строки за раз и/или выполнение явной десериализации и приведения как на отправляющей, так и на принимающей стороне, имитацию массивов, подобных C или Fortran, с помощью одномерного массива и указателей на примитивные типы с помощью одноэлементных массивов, что приводит к стилям программирования, весьма далеким от соглашений Java.

Другая система передачи сообщений Java — MPJ Express. [34] Последние версии могут выполняться в кластерных и многоядерных конфигурациях. В кластерной конфигурации он может выполнять параллельные приложения Java на кластерах и в облаках. Здесь сокеты Java или специализированные соединения ввода-вывода, такие как Myrinet, могут поддерживать обмен сообщениями между процессами MPJ Express. Он также может использовать собственную реализацию MPI на языке C, используя свое собственное устройство. В многоядерной конфигурации параллельное приложение Java выполняется на многоядерных процессорах. В этом режиме процессы MPJ Express представлены потоками Java.

Джулия

Существует оболочка языка Julia для MPI. [35]

МАТЛАБ

Существует несколько академических реализаций MPI с использованием MATLAB . MATLAB имеет собственную библиотеку параллельного расширения, реализованную с использованием MPI и PVM .

OCaml

Модуль OCamlMPI [36] реализует большое подмножество функций MPI и активно используется в научных вычислениях. Программа OCaml из 11 000 строк была «MPI-ифицирована» с использованием модуля, с дополнительными 500 строками кода и небольшой реструктуризацией и работала с превосходными результатами на 170 узлах суперкомпьютера. [37]

ПАРИ/ГП

PARI/GP может быть построен [38] для использования MPI в качестве многопоточного движка, что позволяет запускать параллельные программы PARI и GP на кластерах MPI без каких-либо изменений.

Питон

Активно поддерживаемые оболочки MPI для Python включают: mpi4py, [39] numba-mpi [40] и numba-jax. [41]

К прекращенным разработкам относятся: pyMPI , pypar, [42] MYMPI [43] и подмодуль MPI в ScientificPython .

Р

Привязки R MPI включают Rmpi ​​[44] и pbdMPI , [45] где Rmpi ​​фокусируется на параллелизме менеджер-работник , а pbdMPI фокусируется на параллелизме SPMD . Обе реализации полностью поддерживают Open MPI или MPICH2 .

Пример программы

Вот программа «Hello, World!» в MPI, написанная на языке C. В этом примере мы отправляем сообщение «Hello» каждому процессору, тривиально манипулируем им, возвращаем результаты основному процессу и печатаем сообщения.

/*  Тестовая программа MPI "Hello World" */ #include <assert.h> #include <stdio.h> #include <string.h> #include <mpi.h>    int main ( int argc , char ** argv ) { char buf [ 256 ]; int my_rank , num_procs ;          /* Инициализируем инфраструктуру, необходимую для связи */ MPI_Init ( & argc , & argv );   /* Идентифицируем этот процесс */ MPI_Comm_rank ( MPI_COMM_WORLD , & my_rank );   /* Узнать, сколько всего процессов активно */ MPI_Comm_size ( MPI_COMM_WORLD , & num_procs );   /* До этого момента все программы делали одно и то же.  Здесь мы проверяем ранг, чтобы различать роли программ */ if ( my_rank == 0 ) { int other_rank ; printf ( "У нас есть %i процессов. \n " , num_procs );          /* Отправляем сообщения всем остальным процессам */ for ( other_rank = 1 ; other_rank < num_procs ; other_rank ++ ) { sprintf ( buf , "Привет %i!" , other_rank ); MPI_Send ( buf , 256 , MPI_CHAR , other_rank , 0 , MPI_COMM_WORLD ); }                    /* Получаем сообщения от всех других процессов */ for ( other_rank = 1 ; other_rank < num_procs ; other_rank ++ ) { MPI_Recv ( buf , 256 , MPI_CHAR , other_rank , 0 , MPI_COMM_WORLD , MPI_STATUS_IGNORE ); printf ( "%s \n " , buf ); }                    } еще {   /* Получение сообщения от процесса № 0 */ MPI_Recv ( buf , 256 , MPI_CHAR , 0 , 0 , MPI_COMM_WORLD , MPI_STATUS_IGNORE ); assert ( memcmp ( buf , "Hello" , 6 ) == 0 );             /* Отправляем сообщение процессу № 0 */ sprintf ( buf , "Процесс %i прибыл на службу." , my_rank ); MPI_Send ( buf , 256 , MPI_CHAR , 0 , 0 , MPI_COMM_WORLD );          } /* Разрушаем инфраструктуру связи */ MPI_Finalize (); return 0 ; }   

При запуске с 4 процессами должен быть получен следующий результат: [46]

$ mpicc пример.c && mpiexec -n 4 ./a.outУ нас есть 4 процесса.Процесс 1: прибытие на службу.Процесс 2. Прибытие на службу.Процесс 3. Прибытие на службу.

Здесь, mpiexecэто команда, используемая для выполнения примера программы с 4 процессами , каждый из которых является независимым экземпляром программы во время выполнения и имеет назначенные ранги (т.е. числовые идентификаторы) 0, 1, 2 и 3. Имя mpiexecрекомендовано стандартом MPI, хотя некоторые реализации предоставляют похожую команду под именем mpirun. Это MPI_COMM_WORLDкоммуникатор, который состоит из всех процессов.

Модель программирования «одна программа, несколько данных» ( 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 было более ограниченным. Проблемы включают в себя:

  1. Реализации MPI-2 включают ввод-вывод и динамическое управление процессами, а размер промежуточного программного обеспечения существенно больше. Большинство сайтов, использующих системы пакетного планирования, не могут поддерживать динамическое управление процессами. Параллельный ввод-вывод MPI-2 хорошо принят. [ необходима цитата ]
  2. Многие программы MPI-1.2 были разработаны до MPI-2. Проблемы переносимости изначально замедлили принятие, хотя более широкая поддержка уменьшила это.
  3. Многие приложения MPI-1.2 используют только подмножество этого стандарта (16–25 функций) без реальной необходимости в функциональности MPI-2.

Будущее

Некоторые аспекты будущего MPI кажутся солидными; другие — менее. Форум MPI возобновил работу в 2007 году, чтобы прояснить некоторые вопросы MPI-2 и изучить разработки для возможного MPI-3, что привело к появлению версий MPI-3.0 (сентябрь 2012 г.) и MPI-3.1 (июнь 2015 г.).

Архитектуры меняются, с большей внутренней параллельностью ( многоядерность ), лучшим мелкозернистым управлением параллельностью (многопоточность, сродство) и большим количеством уровней иерархии памяти . Многопоточные программы могут использовать преимущества этих разработок легче, чем однопоточные приложения. Это уже привело к появлению отдельных дополнительных стандартов для симметричной многопроцессорной обработки , а именно OpenMP . MPI-2 определяет, как соответствующие стандарту реализации должны решать проблемы многопоточности, но не требует, чтобы реализации были многопоточными или даже потокобезопасными. MPI-3 добавляет возможность использовать параллелизм с общей памятью в пределах узла. Реализации MPI, такие как Adaptive MPI, Hybrid MPI, Fine-Grained MPI, MPC и другие, предлагают расширения стандарта MPI, которые решают различные проблемы в MPI.

Астрофизик Джонатан Дурси написал статью, в которой назвал MPI устаревшим, указав на более новые технологии, такие как язык Chapel , Unified Parallel C , Hadoop , Spark и Flink . [47] В то же время почти все проекты в рамках проекта Exascale Computing Project явно построены на MPI; было показано, что MPI масштабируется до самых больших машин по состоянию на начало 2020-х годов и, как широко считается, останется актуальным еще долгое время.

Смотрите также

Ссылки

  1. ^ "Интерфейс передачи сообщений :: Высокопроизводительные вычисления". hpc.nmsu.edu . Получено 2022-08-06 .
  2. ^ Walker DW (август 1992 г.). Стандарты передачи сообщений в среде распределенной памяти (PDF) (Отчет). Национальная лаборатория Ок-Ридж, штат Теннесси (США), Центр исследований параллельных вычислений (CRPC). стр. 25. OSTI  10170156. ORNL/TM-12147 . Получено 18 августа 2019 г.
  3. ^ Форум MPI, CORPORATE (15–19 ноября 1993 г.). "MPI: Интерфейс передачи сообщений". Труды конференции ACM/IEEE 1993 г. по суперкомпьютерам . Суперкомпьютерные вычисления '93. Портленд, Орегон, США: ACM. стр. 878–883. doi :10.1145/169627.169855. ISBN 0-8186-4340-4.
  4. ^ Нильсен, Франк (2016). "2. Введение в MPI: Интерфейс передачи сообщений". Введение в HPC с MPI для науки о данных. Springer. С. 195–211. ISBN 978-3-319-21903-5.
  5. ^ Гропп, Ласк и Скьеллум 1996, стр. 3
  6. ^ Sur, Sayantan; Koop, Matthew J.; Panda, Dhabaleswar K. (4 августа 2017 г.). "MPI и связь --- Высокопроизводительный и масштабируемый MPI через InfiniBand с уменьшенным использованием памяти: углубленный анализ производительности". Труды конференции ACM/IEEE 2006 года по суперкомпьютерам - SC '06 . ACM. стр. 105. doi :10.1145/1188455.1188565. ISBN 978-0769527000. S2CID  818662.
  7. ^ KNEM: Высокопроизводительная внутриузловая связь MPI «MPICH2 (начиная с версии 1.1.1) использует KNEM в DMA LMT для повышения производительности больших сообщений в пределах одного узла. Open MPI также включает поддержку KNEM в своем компоненте SM BTL с версии 1.5. Кроме того, NetPIPE включает бэкэнд KNEM с версии 3.7.2».
  8. ^ "FAQ: Настройка характеристик времени выполнения MPI sm-коммуникаций". www.open-mpi.org .
  9. ^ https://software.intel.com/en-us/articles/an-introduction-to-mpi-3-shared-memory-programming?language=en "Стандарт MPI-3 представляет другой подход к гибридному программированию, который использует новую модель MPI Shared Memory (SHM)"
  10. ^ Общая память и MPI 3.0 «Можно запустить различные тесты, чтобы определить, какой метод лучше всего подходит для конкретного приложения, будь то использование MPI + OpenMP или расширений MPI SHM. В довольно простом тестовом случае ускорение по сравнению с базовой версией, использующей связь точка-точка, достигало 5 раз, в зависимости от сообщения».
  11. ^ Использование общей памяти MPI-3 в качестве многоядерной системы программирования (слайды презентации PDF)
  12. Содержание — Сентябрь 1994, 8 (3-4). Hpc.sagepub.com. Получено 24.03.2014.
  13. ^ Документы MPI. Mpi-forum.org. Получено 24.03.2014.
  14. ^ Гропп, Ласк и Скьеллум 1999b, стр. 4–5.
  15. ^ MPI: Стандарт интерфейса передачи сообщений, версия 3.1, Форум интерфейса передачи сообщений, 4 июня 2015 г. http://www.mpi-forum.org. Получено 16 июня 2015 г.
  16. ^ ab "Правила сопоставления типов". mpi-forum.org .
  17. ^ "Страница руководства MPI_Gather(3) (версия 1.8.8)". www.open-mpi.org .
  18. ^ "MPI_Get_address". www.mpich.org .
  19. ^ Обоснование механизма скелета/контента Boost.MPI (графики сравнения производительности были получены с помощью NetPIPE )
  20. ^ Гропп, Ласк и Скьеллинг 1999b, стр. 7
  21. ^ Гропп, Ласк и Скьеллинг 1999b, стр. 5–6.
  22. ^ "Умножение разреженной матрицы на вектор с использованием библиотеки ввода-вывода MPI" (PDF) .
  23. ^ "Просеивание данных и коллективный ввод-вывод в ROMIO" (PDF) . IEEE. Февраль 1999.
  24. ^ Чен, Йонг; Сан, Сянь-Хе; Такур, Раджив; Рот, Филип К.; Гропп, Уильям Д. (сентябрь 2011 г.). «LACIO: Новая коллективная стратегия ввода-вывода для параллельных систем ввода-вывода». IEEE International Parallel & Distributed Processing Symposium 2011 г. IEEE. стр. 794–804. CiteSeerX 10.1.1.699.8972 . doi :10.1109/IPDPS.2011.79. ISBN  978-1-61284-372-8. S2CID  7110094.
  25. ^ Тенг Ван; Кевин Васко; Чжо Лю; Хуэй Чэнь; Вэйкуань Юй (2016). «Улучшение параллельного ввода/вывода с помощью кросс-бандл-агрегации». Международный журнал приложений высокопроизводительных вычислений . 30 (2): 241–256. doi :10.1177/1094342015618017. S2CID  12067366.
  26. ^ Ван, Тенг; Васко, Кевин; Лю, Чжо; Чэнь, Хуэй; Ю, Вэйкуань (ноябрь 2014 г.). «BPAR: фреймворк параллельной агрегации на основе пакетов для выполнения разделенного ввода-вывода». Международный семинар 2014 г. по масштабируемым вычислительным системам с интенсивным использованием данных . IEEE. стр. 25–32. doi :10.1109/DISCS.2014.6. ISBN 978-1-4673-6750-9. S2CID  2402391.
  27. ^ cea-hpc. "cea-hpc/wi4mpi: Интерфейс-оболочка для MPI". GitHub .
  28. ^ mpicc. Mpich.org. Получено 24.03.2014.
  29. ^ Чистый Mpi.NET
  30. ^ "MPI.NET: Высокопроизводительная библиотека C# для передачи сообщений". www.osl.iu.edu .
  31. ^ "Домашняя страница mpiJava". www.hpjava.org .
  32. ^ "Введение в API mpiJava". www.hpjava.org .
  33. ^ "Спецификация API MPJ". www.hpjava.org .
  34. ^ "Проект MPJ Express". mpj-express.org .
  35. ^ JuliaParallel/MPI.jl, Параллельная Джулия, 2019-10-03 , получено 2019-10-08
  36. ^ "Ксавье Лерой - Программное обеспечение". cristal.inria.fr .
  37. ^ Архивы списка рассылки Caml > Сообщение от Ярона М. Мински. Caml.inria.fr (15.07.2003). Получено 24.03.2014.
  38. ^ "Введение в параллельные GP" (PDF) . pari.math.u-bordeaux.fr .
  39. ^ "mpi4py".
  40. ^ "нумба-мпи".
  41. ^ "mpi4jax".
  42. ^ "Архив Google Code — долгосрочное хранилище для хостинга проектов Google Code". code.google.com .
  43. ^ Теперь часть Пидусы
  44. ^ Ю, Хао (2002). «Rmpi: Параллельные статистические вычисления в R». R News .
  45. ^ Чэнь, Вэй-Чэнь; Остроухов, Джордж; Шмидт, Дрю; Патель, Прагнешкумар; Юй, Хао (2012). «pbdMPI: Программирование с использованием больших данных — Интерфейс к MPI».
  46. ^ Выходной фрагмент был создан на обычной настольной системе Linux с установленным Open MPI. Дистрибутивы обычно помещают команду mpicc в пакет openmpi-devel или libopenmpi-dev и иногда требуют запустить "module add mpi/openmpi-x86_64" или что-то подобное, прежде чем mpicc и mpiexec станут доступны.
  47. ^ «HPC умирает, а MPI убивает его». www.dursi.ca .

Дальнейшее чтение

Внешние ссылки