Главная страница

Программирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В.. Программирование для многопроцессорных систем в стандарте MPI -. Организация вычислений в многопроцессорных системах


Скачать 1.61 Mb.
НазваниеОрганизация вычислений в многопроцессорных системах
АнкорПрограммирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В..pdf
Дата15.03.2018
Размер1.61 Mb.
Формат файлаpdf
Имя файлаПрограммирование для многопроцессорных систем в стандарте MPI - .pdf
ТипКонтрольные вопросы
#16702
КатегорияИнформатика. Вычислительная техника
страница4 из 26
1   2   3   4   5   6   7   8   9   ...   26
Глава 3. ПАРНЫЕ МЕЖПРОЦЕССНЫЕ ОБМЕНЫ
3.1. ВВЕДЕНИЕ
Главы 3
− 6 написаны в соответствии со стандартом MPI-1.2 [20,
11], также использовались книги [4, 5, 6,7] и другие документы.
Передача и прием сообщений процессами – это базовый коммуни- кационный механизм
MPI. Основными операциями парного обмена являются операции
send
(послать)
и
receive
(получить). Их исполь- зование иллюстрируется следующим примером:
#include "mpi.h" main( argc, argv ) 7 int argc; char **argv;
{ char message[20]; int myrank;
MPI_Status status;
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &myrank ); if (myrank == 0) /* код для процесса 0 */
{ strcpy(message,"Hello, there");
MPI_Send(message,strlen(message),MPI_CHAR,1,99,
MPI_COMM_WORLD);
} else /* код для процесса 1 */
{ MPI_Recv(message, 20, MPI_CHAR, 0, 99, MPI_COMM_WORLD,
&status); printf("received :%s:\n", message);
}
MPI_Finalize();
}
В этом примере процесс с номером 0 (
myrank = 0
) посылает со- общение процессу с номером 1, используя операцию посылки
MPI_Send
. Эта операция описывает буфер посылающего процесса, из которого извлекаются посылаемые данные. В приведенном примере посылающий буфер состоит из накопителя в памяти процесса 0, со- держащего переменную
message
Размещение, размер и тип буфера

46
посылающего процесса описываются первыми тремя параметрами операции
send.
Посланное сообщение будет содержать 13 символов этой переменной. Операция посылки также связывает с сообщением его атрибуты. Атрибуты определяют номер процесса-получателя со- общения и содержат различную информацию, которая может быть использована операцией
receive
, чтобы выбрать определенное сооб- щение среди других. Последние три параметра операции посылки описывают атрибуты посланного сообщения. Процесс 1 (
myrank = 1
) получает это сообщение, используя операцию приема
MPI_Recv,
и данные сообщения записываются в буфер процесса-получателя. В приведенном примере буфер получателя состоит из накопителя в па- мяти процесса один, содержащего строку
message
. Первые три пара- метра операции приема описывают размещение, размер и тип буфера приема. Следующие три параметра необходимы для выбора входного сообщения. Последний параметр необходим для возврата информации о только что полученном сообщении.
3.2. ОПЕРАЦИИ БЛОКИРУЮЩЕЙ ПЕРЕДАЧИ
И БЛОКИРУЮЩЕГО ПРИЕМА
3.2.1. Блокирующая передача
MPI_SEND(buf, count, datatype, dest, tag, comm)
IN buf начальный адрес буфера посылки сообщения (альтернатива)
IN count число элементов в буфере посылки (неотрицательное целое)
IN datatype тип данных каждого элемента в буфере передачи (дескриптор)
IN dest номер процесса-получателя (целое)
IN tag тэг сообщения (целое)
IN comm коммуникатор (дескриптор) int MPI_Send (void* buf, int count, MPI_Datatype datatype, int dest, int tag,
MPI_Comm comm)
MPI_SEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERROR)
BUF(*)
INTEGER COUNT, DATATYPE, DEST, TAG, COMM, IERROR void MPI::Comm::Send (const void* buf, int count, const MPI::Datatype& datatype, int dest, int tag) const
Семантика этого блокирующего вызова описана в 3.4.

47
3.2.2. Данные в сообщении
Буфер посылки описывается операцией
MPI_SEND
, в которой указано количество последовательных элементов, тип которых указан в поле
datatype,
начиная с элемента по адресу
buf.
Длина сообщения задается числом элементов, а не числом байт.
Число данных
count
в сообщении может быть равно нулю, это оз- начает, что область данных в сообщении пуста. Базисные типы дан- ных в сообщении соответствуют базисным типам данных используе- мого языка программирования. Список возможного соответствия этих типов данных для языка Fortran и MPI представлен ниже.
MPI datatype
Fortran datatype
MPI_INTEGER INTEGER
MPI_REAL REAL
MPI_DOUBLE_PRECISION
DOUBLE PRECISION
MPI_COMPLEX COMPLEX
MPI_LOGICAL LOGICAL
MPI_CHARACTER CHARACTER(1)
MPI_BYTE
MPI_PACKED
Список соответствия типов данных для языка С и MPI дан ниже.
MPI datatype
C datatype
MPI_CHAR signed char
MPI_SHORT signed short int
MPI_INT signed int
MPI_LONG signed long int
MPI_UNSIGNED_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_BYTE
и
MPI_PACKED
не имеют соответствия в язы- ках С или Fortran. Значением типа
MPI_BYTE
является байт. Байт не интерпретируется и отличен от символа. Различные машины могут иметь различное представление для символов или могут использовать

48
для представления символов более одного байта. С другой стороны, байт имеет то же самое двоичное значение на всех машинах.
3.2.3. Атрибуты сообщения
В дополнение к описанию данных сообщение несет информацию, которая используется, чтобы различать и выбирать сообщения. Эта информация состоит из фиксированного количества полей, которые в совокупности называются
атрибутами
сообщения. Эти поля таковы:
source, destination, tag, communicator
(номер процесса-отправителя сообщения, номер процесса-получателя, тэг, коммуникатор).
Целочисленный аргумент тэг используется, чтобы различать типы сообщений. Диапазон значений тэга находится в пределах 0,…,UB, где верхнее значение UB зависит от реализации. MPI требует, чтобы
UB было не менее 32767.
Аргумент
comm
описывает коммуникатор, который используется в операции обмена. Коммуникатор описывает коммуникационный контекст коммуникационной операции. Сообщение всегда принима- ется внутри контекста, в котором оно было послано; сообщения, по- сланные в различных контекстах, не взаимодействуют.
Коммуникатор также описывает ряд процессов, которые разделя- ют этот коммуникационный контекст. Эта группа процессов упоря- дочена, и процессы определяются их номером внутри этой группы: диапазон значений для
dest
есть
0,...,n-1, где n есть число процессов в группе
В MPI предопределен коммуникатор
MPI_COMM_WORLD
. Он разрешает обмен для всех процессов, которые доступны после ини- циализации MPI, и процессы идентифицируются их номерами в груп- пе
MPI_COMM_WORLD
3.2.4. Блокирующий прием
MPI_RECV (buf, count, datatype, source, tag, comm, status)
OUT buf начальный адрес буфера процесса-получателя (альтернатива)
IN count число элементов в принимаемом сообщении (целое)
IN datatype тип данных каждого элемента сообщения (дескриптор)
IN source номер процесса-отправителя (целое)
IN tag тэг сообщения (целое)
IN comm коммуникатор (дескриптор)
OUT status параметры принятого сообщения (статус) int MPI_Recv (void* buf, int count, MPI_Datatype datatype, int source, int tag,
MPI_Comm comm, MPI_Status *status)

49
MPI_RECV(BUF, COUNT, DATATYPE, SOURCE, TAG, COMM, STATUS,
IERROR)
BUF(*)
INTEGER COUNT, DATATYPE, SOURCE, TAG, COMM,
STATUS(MPI_STATUS_SIZE), IERROR void MPI::Comm::Recv (void* buf, int count, const MPI::Datatype& datatype, int source, int tag) const
Буфер получения состоит из накопителя, содержащего последова- тельность элементов, размещенных по адресу
buf
Тип элементов указан в поле
datatype
. Длина получаемого сооб- щения должна быть равна или меньше длины буфера получения, в противном случае будет иметь место ошибка переполнения. Если со- общение меньше размера буфера получения, то в нем модифицируют- ся только ячейки, соответствующие длине сообщения.
Прием сообщения осуществляется, если его атрибуты соответст- вуют значениям источника, тэга и коммуникатора, которые указаны в операции приема. Процесс-получатель может задавать значение
MPI_ANY_SOURCE
для отправителя и/или значение
MPI_ANY_TAG
для тэга, определяя, что любой отправитель и/или тэг разрешен. Нельзя задать произвольное значение для
comm
. Следо- вательно, сообщение может быть принято, если оно адресовано дан- ному получателю и имеет соответствующий коммуникатор.
Тэг сообщения задается аргументом
tag
операции приема. Аргу- мент отправителя, если он отличен от
MPI_ANY_SOURCE
, задается как номер внутри группы процессов, связанной с тем же самым ком- муникатором. Следовательно, диапазон значений для аргумента от- правителя есть
{0,...,n-1}
U
{MPI_ANY_SOURCE}
, где
n
есть количе- ство процессов в этой группе.
Отметим ассиметрию между операциями посылки и приема. Опе- рация приема допускает получение сообщения от произвольного от- правителя, в то время как в операции посылки должен быть указан уникальный получатель.
Допускается ситуация, когда имена источника и получателя сов- падают, то есть процесс может посылать сообщение самому себе (это небезопасно, поскольку может привести к дедлоку (
deadlock
)).

50
3.2.5. Возвращаемая статусная информация
Источник или тэг принимаемого сообщения могут быть неизвест- ны, если в операции приема были использованы значения типа
ANY
Иногда может потребоваться возвратить различные коды ошибок для каждого запроса. Эта информация возвращается с помощью аргу- мента
status
операции
MPI_RECV.
Тип аргумента
status
определяется
MPI. Статусные переменные размещаются пользователем явно, то есть они не являются системны- ми объектами.
В языке С
status
есть структура, которая содержит три поля, назы- ваемые
MPI_SOURCE, MPI_TAG
и
MPI_ERROR
. Следовательно,
status.MPI_SOURCE
,
status.MPI_TAG
и
status.MPI_ERROR
со- держат источник, тэг и код ошибки принятого сообщения.
В языке Fortran
status
есть массив целых значений размера
MPI_STATUS_SIZE
. Константы
MPI_SOURCE, MPI_TAG
и
MPI_ERROR
определяют объекты, которые хранят поля источника, тэга и ошибки.
Следовательно,
status(MPI_SOURCE),
status(MPI_TAG)
и
status(MPI_ERROR)
содержат соответственно источник, тэг и код ошибки принимаемого сообщения.
Вызовы передачи сообщений не модифицируют значения полей кода ошибки статусных переменных. Статусный аргумент также воз- вращает информацию о длине принятого сообщения. Эта информация не является доступной непосредственно, как поле статусной перемен- ной, и требуется вызов
MPI_GET_COUNT
, чтобы «декодировать» эту информацию.
MPI_GET_COUNT(status, datatype, count)
IN status статус операции приема (статус )
IN datatype тип данных каждого элемента приемного буфера (дескриптор)
OUT count количество полученных единиц (целое)
int MPI_Get_count (MPI_Status *status,MPI_Datatype datatype, int *count)
MPI_GET_COUNT(STATUS, DATATYPE, COUNT, IERROR)
INTEGER STATUS(MPI_STATUS_SIZE), DATATYPE, COUNT, IERROR int Status
::
Get_count (const MPI :: Datatype& datatype) const
Операция
MPI_GET_COUNT
возвращает число полученных эле- ментов. Аргумент
datatype
следует сопоставлять с аргументом из операции приема, которая устанавливает статусную переменную.

51
3.3. СООТВЕТСТВИЕ ТИПОВ ДАННЫХ
И ПРЕОБРАЗОВАНИЕ ДАННЫХ
3.3.1. Правила соответствия типов данных
Передача данных содержит следующие три фазы:
1) данные выталкиваются из буфера процесса-отправителя, и части сообщения объединяются;
2) сообщение передается от отправителя к получателю;
3) данные выделяются из получаемого сообщения и помещаются в буфер получателя.
Соответствие типов должно отслеживаться на каждой из трех фаз:
• тип каждой переменной в буфере посылки должен соответствовать типу, указанному для этого элемента в операции посылки;
• тип, описанный в операции посылки, должен соответствовать ти- пу, указанному в операции приема;
• тип каждой переменной в приемном буфере должен соответство- вать типу, указанному для нее в операции приема.
Программа, в которой не соблюдаются эти три правила, является неверной.
Типы отправителя и получателя (фаза два) соответствуют друг другу, если обе операции используют одинаковые названия. Это озна- чает, что
MPI_INTEGER
соответствует
MPI_INTEGER, MPI_REAL
соответствует
MPI_REAL
, и так далее.
Тип переменной в хост–программе (главной программе) соответ- ствует типу, указанному в операции обмена, если название типа дан- ных, используемое этой операцией, соответствует базисному типу пе- ременной хост–программы. Например, элемент с названием типа
MPI_INTEGER
соответствует в языке Fortran переменной типа
INTEGER
. Таблица, описывающая соответствие для языков Fortran и
C, представлена в параграфе 3.2.2.
Имеется два исключения из этого последнего правила: элемент с названием типа
MPI_BYTE
или
MPI_PACKED
может соответство- вать любому байту памяти (на байт-адресуемой машине), без учета типа переменной, которая содержит этот байт. Тип
MPI_PACKED
используется для передачи данных, которые были явно упакованы, или для получения данных, которые будут явно распакованы (3.10).
Тип
MPI_BYTE
позволяет передавать двоичное значение байта из памяти.

52
Правила соответствия типов можно разделить на три категории:
• Коммуникация типизированных значений: типы данных соответ- ствующих элементов в программе передачи, в вызове операции передачи, в вызове операции приема и в программе приема долж- ны соответствовать друг другу.
• Коммуникация нетипизированных значений: нет никаких требова- ний по типам соответствующих элементов в передающей и при- нимающей программах.
• Коммуникация, применяющая упакованные данные, где исполь- зуется
MPI_PACKED
Пример
3.1.
Отправитель и получатель указывают типы соответствия.
CALL MPI_COMM_RANK(comm, rank, ierr)
IF(rank.EQ.0) THEN
CALL MPI_SEND(a(1), 10, MPI_REAL, 1, tag, comm, ierr)
ELSE
CALL MPI_RECV(b(1), 15, MPI_REAL, 0, tag, comm, status, ierr)
END IF
Код корректен, если a, b – действительные массивы размера ≥ 10.
Пример 3.2.
Отправитель и получатель указывают разные типы.
CALL MPI_COMM_RANK(comm, rank, ierr)
IF(rank.EQ.0) THEN
CALL MPI_SEND(a(1), 10, MPI_REAL, 1, tag, comm, ierr)
ELSE
CALL MPI_RECV(b(1), 40, MPI_BYTE, 0, tag, comm, status, ierr)
END IF
Код ошибочен: отправитель и получатель описывают различные типы данных.
Пример 3.3.
Отправитель и получатель описывают передачу нетипи- зированных значений.
CALL MPI_COMM_RANK(comm, rank, ierr)
IF(rank.EQ.0) THEN
CALL MPI_SEND(a(1), 40, MPI_BYTE, 1, tag, comm, ierr)
ELSE
CALL MPI_RECV(b(1), 60, MPI_BYTE, 0, tag, comm, status, ierr)
END IF

53
Код правилен безотносительно к типу и размеру а и b (кроме слу- чая, когда эти результаты выходят за границы памяти).
3.3.2. Преобразование данных
Одной из целей MPI является поддержка параллельных вычисле- ний в неоднородной среде. Связь в такой среде может потребовать следующего преобразования данных:
• преобразования типа – изменяется тип данных значения, например округлением REAL в INTEGER;
• преобразования представления – изменяется двоичное представле- ние значения, например, от Hex floating point к IEEE floating point.
Правила соответствия типов приводят к тому, что обмен в MPI ни- когда не влечет за собой преобразования типов. С другой стороны
MPI требует, чтобы преобразование представления выполнялось, ко- гда типизированное значение передается через среды, которые ис- пользуют различные представления для типов данных этих значений.
MPI не описывает правила для преобразования представления. Пред- полагается, что такое преобразование должно сохранять целые, логи- ческие или знаковые значения и преобразовывать значения с плаваю- щей точкой к ближайшему значению, которое может быть представ- лено на целевой системе.
Во время преобразования с плавающей точкой могут иметь место исключения по переполнению и потере значимости. Преобразование целых также может приводить к исключениям, когда значения, кото- рые могут быть представлены в одной системе, не могут быть пред- ставлены в другой системе. Исключения при преобразовании пред- ставления приводят к невозможности обмена. Ошибка имеет место либо на операции посылки, либо на операции приема, либо на обеих операциях.
Если значение, посылаемое в сообщении, не типизировано (на- пример, типа
MPI_BYTE
), тогда двоичное представление байта, хра- нимое на стороне получателя, идентично двоичному представлению байта, загруженного на стороне отправителя. Это сохраняется вне за- висимости от того, работают ли отправитель и получатель в одной и той же или различающихся средах.
Никакого преобразования не нужно, когда программа MPI работа- ет в однородной системе – все процессы выполняются в той же самой среде.

54
Рассмотрим примеры 3.1 – 3.3. Первая программа правильна, если a и b являются действительными массивами размера ≥ 10. Если отпра- витель и получатель работают в различных средах, тогда десять дей- ствительных значений, которые извлекаются из буфера отправителя, будут преобразованы в представление для действительных чисел на приемной стороне прежде, чем они будут записаны в приемный бу- фер. В то время, как число действительных чисел, извлекаемых из бу- фера отправителя, равно числу действительных чисел, хранимых в приемном буфере, то число хранимых байтов не обязано быть равным числу загруженных байтов. Например, отправитель может использо- вать четырехбайтовое представление для действительных чисел, а по- лучатель – восьмибайтовое.
Вторая программа содержит ошибки, и ее поведение является не- определенным.
Третья программа правильная. Точно та же последовательность из сорока байтов, которая была загружена из буфера посылки, будет за- писана в приемный буфер, даже если получатель и отправитель рабо- тают в различных средах. Посланное сообщение имеет точно ту же длину и точно то же двоичное представление, как и принятое сообще- ние. Если a и b принадлежат к различным типам или они имеют оди- наковый тип, но различное представление, то биты, хранимые в при- емном буфере, могут кодировать значения, которые отличаются от значений, закодированных теми же битами в буфере передачи.
Преобразование представления также относится и к атрибутам со- общения: источник, приемник и тэг являются целыми числами и мо- гут нуждаться в преобразовании. MPI не поддерижвает межъязыко- вый обмен. Поведение программы не определено, если сообщение по- слано процессом в языке С, а принято процессом в языке Fortran.
1   2   3   4   5   6   7   8   9   ...   26


написать администратору сайта