Санкт-Петербургский государственный университет
Опубликован: 11.02.2010 | Доступ: свободный | Студентов: 530 / 93 | Оценка: 4.41 / 4.44 | Длительность: 08:19:00
Специальности: Программист
Лекция 3:

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

Аннотация: В данной лекции описываются основные сведения об инструментальном средстве параллельного программирования MPI. Описывается модель параллельной программы, привязки к языкам программирования Фортран и C

Далее приводится описание свободно распространяемой версии MPI - MPICH 1.2.7, соответствующей спецификации MPI 1.

Модель параллельной программы в MPI

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

Каждому процессу в области взаимодействия назначается уникальный числовой идентификатор - ранг,значение которого от 0 до np - 1 ( np - число процессов). Ранги, назначаемые одному и тому же процессу в разных коммуникаторах, вообще говоря, различны.

Структура программы, написанной по схеме хозяин/работник, приведена ниже.

program para
...
if  (ранг процесса = рангу мастер-процесса)  then
код мастер-процесса else
код подчиненного процесса (подчиненных процессов)
endif
end

Каждый экземпляр программы уже в процессе своего выполнения определяет, является ли он мастер-процессом. Затем, в зависимости от результата этой проверки, выполняется одна из ветвей условного оператора. Первая ветвь соответствует мастер-задаче, а вторая - подчиненной задаче. Способы взаимодействия между подзадачами определяются программистом.

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

Сообщения

Сообщение содержит пересылаемые данные и служебную информацию. Для того, чтобы передать сообщение, необходимо указать:

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

Тег - это задаваемое пользователем целое число от 0 до 32767, которое играет роль идентификатора сообщения и позволяет различать сообщения, приходящие от одного процесса. Теги могут использоваться и для соблюдения определенного порядка приема сообщений.

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

Разновидности обменов сообщениями

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

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

При выполнении глобальных операций используются коллективные обмены. Асинхронные коммуникации реализуются с помощью запросов о получении сообщений. Имеется несколько разновидностей двухточечного обмена.

  • Блокирующие прием/передача - приостанавливают выполнение процесса на время приема сообщения.
  • Неблокирующие прием/передача - выполнение процесса продолжается в фоновом режиме, а программа в нужный момент может запросить подтверждение завершения приема сообщения.
  • Синхронный обмен - сопровождается уведомлением об окончании приема сообщения.
  • Асинхронный обмен - уведомлением не сопровождается.

Привязка к языку Fortran

Имена подпрограмм и констант MPI в программах на языке Fortran начинаются с MPI _. При вызове подпрограмм коды завершения передаются через дополнительный параметр целого типа (находится на последнем месте в списке параметров подпрограммы). Код успешного завершения - MPI_SUCCESS. Константы и другие объекты MPI описываются в файле mpif.h, который включается в MPI -программу с помощью оператора include.

В некоторых подпрограммах используется переменная status, которая является массивом стандартного целого типа. Его размер MPI_STATUS_SIZE.

При обращении к подпрограммам MPI используются типы данных MPI, для большинства из которых имеется соответствие базовым типам языка (см. табл. 3.1)

Типы MPI_Datatype и MPI_Comm - эмулируются стандартным целым типом языка Fortran (Integer).

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

Таблица 3.1. Типы данных MPI для языка Fortran
Тип данных MPI Тип данных Fortran
MPI_INTEGER Integer
MPI_REAL Real
MPI_DOUBLE_PRECISION Double precision
MPI_DOUBLE_COMPLEX Double complex
MPI_COMPLEX Complex
MPI_LOGICAL Logical
MPI_CHARACTER Character
MPI_BYTE Нет соответствия
MPI_PACKED Нет соответствия
Типы, которые имеются не во всех реализациях MPI
MPI_INTEGER1 Integer*1
MPI_INTEGER2 Integer*2
MPI_INTEGER4 Integer*4
MPI_REAL4 Real*4
MPI_REAL8 Real*8

Привязка к языку C

В программах на языке C имена подпрограмм имеют вид Класс_действие_подмножество или Класс_действие. В C++ подпрограмма является методом для определенного класса, имя имеет в этом случае вид MPI::Класс::действие_подмножество. Для некоторых действий введены стандартные наименования: Create - создание нового объекта, Get - получение информации об объекте, Set - установка параметров объекта, Delete - удаление информации, Is - запрос о том, имеет ли объект указанное свойство.

Имена констант MPI записываются в верхнем регистре. Их описания находятся в заголовочном файле mpi.h.

Входные параметры функций передаются по значению, а выходные (и INOUT ) - по ссылке. Соответствие типов MPI стандартным типам языка C приведено в табл. 3.2.

Коды завершения

В MPI приняты стандартные соглашения о кодах завершения вызовов подпрограмм. Так, например, возвращаются значения MPI_SUCCESS - при успешном завершении вызова и MPI_ERR_OTHER - обычно при попытке повторного вызова процедуры MPI_Init.

Вместо числовых кодов в программах обычно используют специальные именованные константы:

  • MPI_ERR_BUFFER - неправильный указатель на буфер;
  • MPI_ERR_COMM - неправильный коммуникатор;
  • MPI_ERR_RANK - неправильный ранг;
  • MPI_ERR_OP - неправильная операция;
  • MPI_ERR_ARG - неправильный аргумент;
  • MPI_ERR_UNKNOWN - неизвестная ошибка;
  • MPI_ERR_TRUNCATE - сообщение обрезано при приеме;
  • MPI_ERR_INTERN - внутренняя ошибка. Обычно возникает, если системе не хватает памяти.
Таблица 3.2. Типы данных MPI для языка С
Тип данных MPI Тип данных C
MPI_CHAR Signed char
MPI_SHORT Signed short int
MPI_INT Signed int
MPI_LONG Signed long int
MPI_UN SIGNE D_CHAR unsigned char
MPI_UNSIGNED_SHORT unsigned short int
MPI_UNSIGNED unsigned int
MPI_UNSIGNED_LONG unsigned long int
MPI_FLOAT Float
MPI_DOUBLE Double
MPI_LONG_DOUBLE long double
MPI_BYTE Нет соответствия
MPI_PACKED Нет соответствия

Основные понятия MPI

Коммуникатор представляет собой структуру, содержащую либо все процессы, исполняющиеся в рамках данного приложения, либо их подмножество. Процессы, принадлежащие одному и тому же коммуникатору, наделяются общим контекстом обмена. Операции обмена возможны только между процессами, связанными с общим контекстом, то есть, принадлежащие одному и тому же коммуникатору (рис. 3.1). Каждому коммуникатору присваивается идентификатор. В MPI есть несколько стандартных коммуникаторов:

  • MPI_COMM_WORLD - включает все процессы параллельной программы;
  • MPI_COMM_SELF - включает только данный процесс;
  • MPI_COMM_NULL - пустой коммуникатор, не содержит ни одного процесса.

В MPI имеются процедуры, позволяющие создавать новые коммуникаторы, содержащие подмножества процессов.

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

Рис. 3.1. Коммуникатор

Ранг процесса представляет собой уникальный числовой идентификатор, назначаемый процессу в том или ином коммуникаторе. Ранги в разных коммуникаторах назначаются независимо и имеют целое значение от 0 до число_процессов - 1 (рис. 3.2).

Ранги процессов

Рис. 3.2. Ранги процессов

Тег (маркер) сообщения - это уникальный числовой идентификатор, который назначается сообщению и позволяет различать сообщения, если в этом есть необходимость. Если тег не требуется, вместо него можно использовать "джокер" MPI_ANY_TAG.

Типовая структура MPI -программы:

program para
...
if (process = master) then
master clause else
slave clause endif end

Различные подпрограммы MPI

Подключение к MPI

int MPI_Init(int *argc, char **argv)

MPI_INIT(IERR)

Аргументы argc и argv требуются только в программах на C, где они задают количество аргументов командной строки запуска программы и вектор этих аргументов. Данный вызов предшествует всем прочим вызовам подпрограмм MPI.

Завершение работы с MPI

p>int MPI_Finalize()

MPI_FINALIZE(IERR)

После вызова данной подпрограммы нельзя вызывать подпрограммы MPI. MPI_FINALIZE должны вызывать все процессы перед завершением своей работы.

Определение размера области взаимодействия

p>int MPI_Comm_size(MPI_Comm comm, int *size)
MPI_COMM_SIZE(COMM., SIZE, IERR)

Входные параметры:

  • comm - коммуникатор.

Выходные параметры:

  • size - количество процессов в области взаимодействия.

Определение ранга процесса

int MPI_Comm_rank(MPI_Comm comm, int *rank)
MPI_COMM_RANK(COMM, RANK, IERR)

Входные параметры:

  • comm- коммуникатор.

Выходные параметры:

  • rank - ранг процесса в области взаимодействия.

Определение имени узла, на котором выполняется данный процесс

MPI_Get_processor_name(char *name, int *resultlen)

MPI_GET_PROCESSOR_NAME(NAME, RESULTLEN, IERR)

Выходные параметры:

  • name - идентификатор вычислительного узла. Массив не менее чем из MPI_MAX_PROCESSOR_NAME элементов;
  • resultlen - длина имени.

Время, прошедшее с произвольного момента в прошлом

double MPI_Wtime()

MPI_WTIME(TIME,   IERR)