Message Passing Interface

Материал из Википедии — свободной энциклопедии
Версия от 14:09, 15 ноября 2025; imported>Alex NB OT (унификация языковых шаблонов)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигации Перейти к поиску

Шаблон:Ложное перенаправление Message Passing Interface (MPI, интерфейс передачи сообщений) — программный интерфейс (API) для передачи информации, который позволяет обмениваться сообщениями между процессами, выполняющими одну задачу. Разработан Уильямом Гроуппом, Шаблон:Нп1 и другими.

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

Стандартизацией MPI занимается MPI Forum. В стандарте MPI описан интерфейс передачи сообщений, который должен поддерживаться как на платформе, так и в приложениях пользователя. В настоящее время существует большое количество бесплатных и коммерческих реализаций MPI. Существуют реализации для языков Фортран 77/90, Java, Си и C++.

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

Стандарты MPI

Первая версия MPI разрабатывалась в 1993—1994 году, и MPI 1 вышла в 1994.

Большинство современных реализаций MPI поддерживают версию 1.1. Стандарт MPI версии 2.0 поддерживается большинством современных реализаций, однако некоторые функции могут быть реализованы не до конца.

В MPI 1.1 (опубликован 12 июня 1995 года, первая реализация появилась в 2002 году) поддерживаются следующие функции:

  • передача и получение сообщений между отдельными процессами;
  • коллективные взаимодействия процессов;
  • взаимодействия в группах процессов;
  • реализация топологий процессов;

В MPI 2.0 (опубликован 18 июля 1997 года) дополнительно поддерживаются следующие функции:

  • динамическое порождение процессов и управление процессами;
  • односторонние коммуникации (Get/Put);
  • параллельный ввод и вывод;
  • расширенные коллективные операции (процессы могут выполнять коллективные операции не только внутри одного коммуникатора, но и в рамках нескольких коммуникаторов).

Версия MPI 2.1 вышла в начале сентября 2008 года.

Версия MPI 2.2 вышла 4 сентября 2009 года.

Версия MPI 3.0 вышла 21 сентября 2012 года.

Функционирование интерфейса

Базовым механизмом связи между MPI процессами является передача и приём сообщений. Сообщение несёт в себе передаваемые данные и информацию, позволяющую принимающей стороне осуществлять их выборочный приём:

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

Операции приёма и передачи могут быть блокирующимися и неблокирующимися. Для неблокирующихся операций определены функции проверки готовности и ожидания выполнения операции.

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

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

Ниже приведён пример программы вычисления числа <math>\pi</math> на языке C с использованием MPI:

<source lang="C"> // Подключение необходимых заголовков

  1. include <stdio.h>
  2. include <math.h>

// Подключение заголовочного файла MPI

  1. include "mpi.h"

// Функция для промежуточных вычислений double f(double a) {

   return (4.0 / (1.0+ a*a));

}

// Главная функция программы int main(int argc, char **argv) {

   // Объявление переменных
   int done = 0, n, myid, numprocs, i;
   double PI25DT = 3.141592653589793238462643;
   double mypi, pi, h, sum, x;
   double startwtime = 0.0, endwtime;
   int namelen;
   char processor_name[MPI_MAX_PROCESSOR_NAME];

   // Инициализация подсистемы MPI
   MPI_Init(&argc, &argv);
   // Получить размер коммуникатора MPI_COMM_WORLD
   // (общее число процессов в рамках задачи)
   MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
   // Получить номер текущего процесса в рамках 
   // коммуникатора MPI_COMM_WORLD
   MPI_Comm_rank(MPI_COMM_WORLD,&myid);
   MPI_Get_processor_name(processor_name,&namelen);

   // Вывод номера потока в общем пуле
   fprintf(stdout, "Process %d of %d is on %s\n", myid,numprocs,processor_name);
   fflush(stdout);

   while(!done)
   {
       // количество интервалов
       if(myid==0)
       {
           fprintf(stdout, "Enter the number of intervals: (0 quits) ");
           fflush(stdout);
           if(scanf("%d",&n) != 1)
           {
               fprintf(stdout, "No number entered; quitting\n");
               n = 0;
           }
           startwtime = MPI_Wtime();
       }
       // Рассылка количества интервалов всем процессам (в том числе и себе)
       MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
       if(n==0)
           done = 1;
       else
       {
           h = 1.0 / (double) n;
           sum = 0.0;
           // Обсчитывание точки, закрепленной за процессом
           for(i = myid + 1 ; (i <= n) ; i += numprocs)
           {
               x = h * ((double)i - 0.5);
               sum += f(x);
           }
           mypi = h * sum;

           // Сброс результатов со всех процессов и сложение
           MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

           // Если это главный процесс, вывод полученного результата
           if(myid==0)
           {
               printf("PI is approximately %.16lf, Error is %.16lf\n", pi, fabs(pi - PI25DT));
               endwtime = MPI_Wtime();
               printf("wall clock time =%lf\n", endwtime-startwtime);
               fflush(stdout);
           }
       }
   }

   // Освобождение подсистемы MPI
   MPI_Finalize();
   return 0;

} </source>

Реализации MPI

  • MPICH — одна из самых первых свободная реализация MPI, работает на UNIX-системах и Windows NT
  • Open MPI — ещё одна свободная реализация MPI. Основана на более ранних проектах FT-MPI, LA-MPI, LAM/MPI и PACX-MPI. Поддерживаются различные коммуникационные системы (в том числе Myrinet).
  • MPI/PRO for Windows NT — коммерческая реализация для Windows NT
  • Intel MPI — коммерческая реализация для Windows / Linux
  • Microsoft MPI входит в состав Compute Cluster Pack SDK. Основан на MPICH2, но включает дополнительные средства управления заданиями. Поддерживается спецификация MPI-2.
  • HP-MPI — коммерческая реализация от HP
  • SGI MPT — платная библиотека MPI от SGI
  • Mvapich — свободная реализация MPI для Infiniband
  • Oracle HPC ClusterTools — бесплатная реализация для Solaris SPARC/x86 и Linux на основе Open MPI
  • MPJ — MPI for Java
  • MPJ Express — MPI на Java

См. также

Ссылки

См. также

Шаблон:ПО для распределенных вычислений