Message Passing Interface

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

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

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), позволяющий читать и изменять область памяти удалённого процесса. Локальный процесс может переносить область памяти удалённого процесса (внутри указанного процессами окна) в свою память и обратно, а также комбинировать данные, передаваемые в удалённый процесс с имеющимися в его памяти данными (например, путём суммирования). Все операции удалённого доступа к памяти не блокирующиеся, однако, до и после их выполнения необходимо вызывать блокирующиеся функции синхронизации.

Пример программы[править | править код]

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

 1 // Подключение необходимых заголовков
 2 #include <stdio.h>
 3 #include <math.h>
 4 // Подключение заголовочного файла MPI
 5 #include "mpi.h"
 6  
 7 // Функция для промежуточных вычислений
 8 double f (double a)
 9 {
10     return (4.0 / (1.0+ a*a));
11 }
12  
13 // Главная функция программы
14 int main (int argc, char **argv)
15 {
16     // Объявление переменных
17     int done = 0, n, myid, numprocs, i;
18     double PI25DT = 3.141592653589793238462643;
19     double mypi, pi, h, sum, x;
20     double startwtime = 0.0, endwtime;
21     int namelen;
22     char processor_name[MPI_MAX_PROCESSOR_NAME];
23  
24     // Инициализация подсистемы MPI
25     MPI_Init(&argc, &argv);
26     // Получить размер коммуникатора MPI_COMM_WORLD
27     // (общее число процессов в рамках задачи)
28     MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
29     // Получить номер текущего процесса в рамках 
30     // коммуникатора MPI_COMM_WORLD
31     MPI_Comm_rank(MPI_COMM_WORLD,&myid);
32     MPI_Get_processor_name(processor_name,&namelen);
33  
34     // Вывод номера потока в общем пуле
35     fprintf(stdout, "Process %d of %d is on %s\n", myid,numprocs,processor_name);
36     fflush(stdout);
37  
38     while(!done)
39     {
40         // количество интервалов
41         if(!myid)
42         {
43             fprintf(stdout, "Enter the number of intervals: (0 quits) ");
44             fflush(stdout);
45             if(!scanf("%d",&n))
46             {
47                 fprintf(stdout, "No number entered; quitting\n");
48                 n = 0;
49             }
50             startwtime = MPI_Wtime();
51         }
52         // Рассылка количества интервалов всем процессам (в том числе и себе)
53         MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
54         if(!n) done = 1;
55         else
56         {
57             h = 1.0 / (double) n;
58             sum = 0.0;
59             // Обсчитывание точки, закрепленной за процессом
60             for(i = myid + 1; (i <= n); i += numprocs)
61             {
62                 x = h * ((double)i - 0.5);
63                 sum += f(x);
64             }
65             mypi = h * sum;
66  
67             // Сброс результатов со всех процессов и сложение
68             MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
69  
70             // Если это главный процесс, вывод полученного результата
71             if(!myid)
72             {
73                 printf("PI is approximately %.16f, Error is %.16f\n", pi, fabs(pi - PI25DT));
74                 endwtime = MPI_Wtime();
75                 printf("wall clock time =%f\n", endwtime-startwtime);
76                 fflush(stdout);
77             }
78         }
79     }
80  
81     // Освобождение подсистемы MPI
82     MPI_Finalize();
83     return 0;
84 }

Реализации MPI[править | править код]

  • MPICH — одна из самых первых свободная реализация MPI, работает на UNIX-системах и Windows NT
  • Open MPI — ещё одна свободная реализация MPI. Основана на более ранних проектах FT-MPI, LA-MPI, LAM/MPI и PACX-MPI. Поддерживаются различные коммуникационные системы (в том числе Myrinet).
  • WMPI — реализация MPI для Windows
  • 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

См. также[править | править код]

Ссылки[править | править код]

См. также[править | править код]