Односторонние обмены

advertisement
Основы параллельного программирования с
использованием MPI
Лекция 8
Немнюгин Сергей Андреевич
Санкт-Петербургский государственный университет
физический факультет
кафедра вычислительной физики
Лекция 8
Аннотация
В заключительной лекции даётся краткий обзор тех возможностей
MPI, которые не рассматривались в предыдущих лекциях. Среди них
атрибуты коммуникатора, односторонние обмены, дополнительные
вопросы организации коллективных обменов, параллельные операции
ввода-вывода, внешние интерфейсы, а также средства управления
процессами из MPI-программы в процессе её выполнения.
Рассматриваются программные инструменты отладки и оптимизации
параллельных программ.
2008
План лекции
 Атрибуты коммуникатора.
 MPI-1 и MPI-2, сравнительный обзор.
 Запуск процессов. Демон mpd.
 Односторонние обмены.
 Взаимодействие между группами процессов.
 Коллективные обмены.
 Параллельные операции ввода-вывода.
 Программные инструменты отладки и оптимизации MPI-программ.
2008
Атрибуты
2008
Атрибуты
Атрибут коммуникатора – дополнительная информация, добавляемая
к коммуникатору с помощью механизма кэширования.
Если какая-то информация записана в качестве атрибута в одном из
процессов, она автоматически становится доступной всем другим
процессам из данного коммуникатора. Специальной организации
пересылок сообщений при этом не требуется, система сама
позаботится о передаче необходимой информации.
Атрибуты определяются только для того коммуникатора, к которому
они присоединены. Они могут дублироваться только при
дублировании коммуникатора - других способов их передачи от
одного коммуникатора другому нет.
2008
Атрибуты
В C атрибуты имеют тип void *. Обычно это указатели на структуры,
которые содержат необходимую информацию или обработчики для
объекта MPI.
В программах на языке Fortran атрибуты имеют тип integer.
Идентификатор атрибута - целое число, которое назначается системой
автоматически и называется ключом атрибута.
Атрибуты бывают системные и пользовательские. Системные
атрибуты не могут модифицироваться программистом. К их числу
относятся топология, адрес обработчика ошибок и некоторые другие.
Значения ключей являются глобальными и могут использоваться
всеми коммуникаторами программы.
2008
Атрибуты
В MPI реализованы (локальные) операции с атрибутами. Подпрограмма:
int MPI_Keyval_create(MPI_Copy_function *copy_fn,
MPI_Delete_function *delete_fn, int *keyval, void *extra_state)
MPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state,
ierr)
предназначена для создания нового ключа атрибута keyval (выходной
параметр). Ключи уникальны для каждого процесса и не видны
пользователю, хотя явным образом хранятся в виде целых значений.
Будучи однажды задан, ключ может быть использован для задания
атрибутов и доступа к ним в любом коммуникаторе. Функция copy_fn
вызывается, когда коммуникатор дублируется подпрограммой
MPI_Comm_dup, а функция delete_fn используется для удаления.
Параметр extra_state задает дополнительную информацию для
функций копирования и удаления.
2008
Атрибуты
Функция MPI_Copy_function определяется следующим образом:
typedef int MPI_Copy_function(MPI_Comm oldcomm, int keyval,
void *extra_state, void *attribute_val_in, void
*attribute_val_out, int *flag)
subroutine copy_function(oldcomm, keyval, extra_state,
attribute_val_in, attribute_val_out, flag, ierr)
2008
Атрибуты
Функция копирования вызывается для каждого значения ключа в
исходном коммуникаторе в произвольном порядке. Каждое обращение
к функции копирования выполняется со значением ключа и
соответствующим ему атрибутом. Если она возвращает значение
флага flag = 0, атрибут удаляется из продублированного
коммуникатора. В противном случае (flag = 1) устанавливается
новое значение атрибута, равное значению, возвращенному в
параметре attribute_val_out.
2008
Атрибуты
Удалить ключ атрибута можно с помощью вызова подпрограммы
:
int MPI_Keyval_free(int *keyval)
MPI_Keyval_free(keyval, ierr)
Используемый атрибут можно удалить, поскольку фактическое
удаление происходит только после того, как будут удалены все ссылки
на атрибут. Эти ссылки должны быть явным образом удалены
программой, например, посредством вызова MPI_Attr_delete 
каждый такой вызов удаляет один экземпляр атрибута, либо вызовом
MPI_Comm_free, который удаляет все экземпляры атрибута, связанные
с удаляемым коммуникатором.
2008
Атрибуты
Подпрограмма:
int MPI_Attr_put(MPI_Comm comm, int keyval, void* attribute)
MPI_Attr_put(comm, keyval, attribute, ierr)
используется для задания атрибута attribute, который в дальнейшем
может использоваться подпрограммой MPI_Attr_get. С атрибутом
ассоциируется значение ключа keyval.
Подпрограмма:
int MPI_Attr_get(MPI_Comm comm, int keyval, void *attribute,
int *flag)
MPI_Attr_get(comm, keyval, attribute, flag, ierr)
возвращает значение атрибута attribute, соответствующее значению
ключа keyval. Первый параметр задает коммуникатор, с которым
связан атрибут.
2008
Атрибуты
Подпрограмма:
int MPI_Attr_delete(MPI_Comm comm, int keyval)
MPI_Attr_delete(comm, keyval, ierr)
удаляет атрибут с указанным значением ключа. Делается это с
помощью функции удаления атрибута delete_fn, заданной при
создании keyval. Параметр comm задает коммуникатор, с которым
связан атрибут.
2008
Атрибуты
Пример
program main_mpi
include 'mpif.h'
integer rank, ierr
integer numprocs, newcomm
integer key, attr, extra
external copy_fun, del_fun
logical flag
call MPI_Init(ierr)
call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
call MPI_Keyval_create(copy_fun, del_fun, key, extra, ierr)
ATTR = 120
call MPI_Attr_put(MPI_COMM_WORLD, key, attr, ierr)
call MPI_Attr_get(MPI_COMM_WORLD, key, attr, flag, ierr)
print *, "PROCESS = ", RANK, " BEFORE DUP ATTRIBUTE = ", attr
call MPI_Comm_dup(MPI_COMM_WORLD, newcomm, ierr)
2008
Атрибуты
call MPI_Attr_get(newcomm, key, attr, flag, ierr)
if (flag) then
print *, "process = ", rank, " after dup attribute = ",
attr
end if
call MPI_Comm_free(newcomm, ierr)
call MPI_Finalize(ierr)
stop
end
2008
Атрибуты
subroutine copy_fun(comm, keyval, extra, attr_in, attr_out,
flag, ierr)
integer comm, keyval, fuzzy, attr_in, attr_out
logical flag
include 'mpif.h'
attr_out = attr_in + 1
flag =.true.
ierr = MPI_SUCCESS
end
subroutine del_fun(comm, keyval, attr, extra, ierr)
integer comm, keyval, attr, extra, ierr
include 'mpif.h'
ierr = MPI_SUCCESS
if(keyval /= MPI_KEYVAL_INVALID) then
attr = attr - 1
end if
return
end
2008
Атрибуты
Результат выполнения программы:
2008
MPI-1 и MPI-2. Сравнительный обзор
2008
MPI-1 и MPI-2. Сравнительный обзор
В спецификации MPI-2 появились новые возможности, превратившие
MPI в ещё более гибкий инструмент разработки параллельных
программ.
Краткий перечень новых (по сравнению с MPI-1) возможностей:
 возможность запуска новых процессов во время выполнения MPIпрограммы;
 односторонние двухточечные обмены;
 параллельные операции ввода-вывода;
 модифицированные привязки к языкам;
 новые предопределённые типы данных;
 расширенные возможности коллективных обменов;
 внешние интерфейсы;
 поддержка многопоточности и другие.
2008
Динамический запуск процессов
2008
Динамический запуск процессов
Возможность запуска новых процессов во время
выполнения MPI-программы
В MPI-1 параллельная программа запускается в определённом и
фиксированном количестве процессов. Это не позволяет
приложению, например, «подстраиваться» под изменяющуюся
трудоёмкость расчёта. В то же время такой инструмент
параллельного программирования как PVM поддерживает
возможность динамического изменения числа процессов
параллельного приложения. Эта возможность появилась в MPI-2.
Дополнительный процесс (несколько процессов) может быть
запущен во время выполнения программы. Процесс может быть
также остановлен.
2008
Динамический запуск процессов
Запуск одного процесса выполняется с помощью обращения к
подпрограмме:
int MPI_Comm_spawn(char *command, char *argv[], int
maxprocs, MPI_Info info, int root, MPI_Comm comm, MPI_Comm
*intercomm, int array_of_errcodes[])
MPI_Comm_spawn(command, argv, maxprocs, info, root, comm,
intercomm, array_of_errcodes, ierror)
Входные параметры:
 command – командная строка запуска процесса;
 argv – аргументы командной строки запуска процесса;
 maxprocs – максимальное количество запускаемых процессов;
 info – указывает системе как и где запускается процесс;
 root – ранг главного процесса.
2008
Динамический запуск процессов
Выходные параметры:
 intercomm – интеркоммуникатор между исходной группой
процессов и вновь запущенными процессами;
 array_of_errcodes – коды завершения для запущенных процессов.
При запуске группы процессов для них создаётся собственный
коммуникатор MPI_COMM_WORLD, отличный от такого же для
родительских процессов. Это коллективная операция. Она
завершается после того, как во всех дочерних процессах состоится
вызов MPI_Init. Завершение данного вызова в родительском процессе
не означает, что в дочерних процессах завершены все вызовы
MPI_Init.
Интеркоммуникатор intercomm содержит родительский процесс в
локальной группе и дочерние процессы.
2008
Динамический запуск процессов
Командная строка запуска дочернего процесса представляет собой
строку, содержащую имя исполняемого файла.
Дочерний процесс обязательно должен вызывать MPI_Init, иначе
результат не определён.
Аргумент
argv
является
массивом
строковых
представляющих аргументы запускаемых программ.
значений,
При вызове MPI_Comm_spawn предприниматеся попытка запустить
maxprocs процессов. Если какой-то процесс не может быть запущен,
возвращается значение MPI_ERR_SPAWN.
Аргумент info создаётся вызовом специальной подпрограммы
MPI_Info_create.
2008
Динамический запуск процессов
В том случае, когда необходимо запустить несколько разных
исполняемых файлов или один файл, но с разными параметрами,
можно использовать подпрограмму MPI_Comm_spawn_multiple.
Опуская подробное описание её параметров, приведём интерфейс:
int MPI_Comm_spawn_multiple(int count, char
*array_of_commands[], char **array_of_argv[], int
array_of_maxprocs[], MPI_Info array_of_info[], int root,
MPI_Comm comm, MPI_Comm *intercomm, int array_of_errcodes[])
MPI Comm_spawn_multiple(count, array_of_commands,
array_of_argv, array_of_ maxprocs, array_of_info, root, comm,
intercomm, array_of_errcodes, ierror)
2008
Динамический запуск процессов
Подпрограмма
MPI_Get_parent
возвращает
интеркоммуникатор вызывающего процесса:
родительский
int MPI_Comm_get_parent(MPI_Comm *parent)
MPI_Comm_get_parent(parent, ierr)
Если данный процесс не является дочерним по отношению к какомулибо другому процессу, возвращается значение «пустого»
коммуникатора MPI_COMM_NULL.
2008
Динамический запуск процессов
Пример
Master
#include "mpi.h"
int main(int argc, char *argv[])
{
int world_size, universe_size, *universe_sizep, flag;
MPI_Comm everyone;
char worker_program[100];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
if (world_size != 1) error("Top heavy with management");
MPI_Attr_get(MPI_COMM_WORLD, MPI_UNIVERSE_SIZE,
&universe_sizep, &flag);
if (!flag) {
printf("This MPI does not support UNIVERSE_SIZE. How many\n\
processes total?");
scanf("%d", &universe_size);
} else universe_size = *universe_sizep;
if (universe_size == 1) error("No room to start workers");
choose_worker_program(worker_program);
2008
Динамический запуск процессов
MPI_Comm_spawn(worker_program, MPI_ARGV_NULL, universe_size1,
MPI_INFO_NULL, 0, MPI_COMM_SELF, &everyone,
MPI_ERRCODES_IGNORE);
MPI_Finalize();
return 0;
}
}
2008
Динамический запуск процессов
Slave
#include "mpi.h"
int main(int argc, char *argv[])
{
int size;
MPI_Comm parent;
MPI_Init(&argc, &argv);
MPI_Comm_get_parent(&parent);
if (parent == MPI_COMM_NULL) error("No parent!");
MPI_Comm_remote_size(parent, &size);
if (size != 1) error("Something's wrong with the parent");
MPI_Finalize();
return 0;
}
2008
Динамический запуск процессов
Демон mpd
В MPI-2 демон mpd играет важную роль. Параллельная программа
может выполняться только если предварительно были запущены
демоны mpd, образующие «кольцо демонов».
 Кольцо демонов создаётся один раз и может быть использовано
многократно, разными программами одного пользователя.
 Кольцо демонов прекращает свой существование в результате
выполнения команды mpdallexit.
 Кольцо демонов одного пользователя не может взаимодействовать
с демонами mpd других пользователей.
 Благодаря демонам mpd запуск MPI-программ выполняется
быстрее.
 Локальный экземпляр MPI-процесса завершается по нажатию
клавиш Ctrl+C, при этом завершаются и все остальные процессы.
 Исключена возможность «зависания» процессов.
Динамический запуск процессов
Запуск демонов (в этом примере 5) выполняется командой:
mpdboot –n 5
Проверка взаимодействия
командой:
демонов
между
собой
выполняется
mpdtrace
Если при выполнении этой команды выводятся сообщения об
ошибках, это говорит о неправильной настройке MPI или локальной
сети.
Завершение работы демонов выполняется командой:
mpdallexit
Взаимодействие между группами
процессов
2008
Взаимодействие между группами
процессов
Взаимодействие между группами процессов
MPI-2 допускает организацию обмена сообщениями между группами
процессов, которые запущены независимо друг от друга.
Это позволяет, например, «подключиться» к параллельной программе
приложению, выполняющему обработку данных.
Эта возможность полезна при создании клиент-серверных
приложений и в других ситуациях.
Основные механизмы взаимодействия:
 связь по имени;
 связь через порт.
2008
Взаимодействие между группами
процессов
Программная реализация взаимодействия:
MPI_Open_port
MPI_Close_port
MPI_Comm_accept
MPI_Publish_name
MPI_Unpublish_name
MPI_Lookup_name
и другие подпрограммы.
2008
Односторонние обмены
2008
Односторонние обмены
Односторонние обмены основаны на механизме удалённого доступа к
памяти (RMA – Remote Memory Access) и позволяют процессу,
инициировавшему обмен, самостоятельно задать параметры обмена
как для источника, так и для адресата сообщения.
Односторонние обмены используются в том случае, когда процесс
«знает», какие данные другого процесса он должен модифицировать, а
процесс-адресат сообщения этого не знает.
Стандартная схема обмена сообщениями в этом случае требует
согласования действий отправителя и получателя сообщения, для чего
могут потребоваться дополнительные затраты времени (например, на
пересылку параметров обмена). При этом объединены функции
коммуникации и синхронизации.
В односторонних обменах эти функции разделены.
2008
Односторонние обмены
2008
Односторонние обмены
Односторонний обмен возможен, если процесс создаёт «окно»,
доступное всем остальным процессам.
Окно создаётся (коллективным) вызовом подпрограммы:
int MPI_Win_create(void *base, MPI_Aint size, int disp_unit,
MPI_Info info, MPI_Comm comm, MPI_Win *win)
MPI_Win_create(base, size, disp unit, info, comm, win,
ierror)
Входные параметры:
 base – адрес окна;
 size – размер окна в байтах;
 disp_unit – масштабный множитель для вычисления смещений;
 info – информационный параметр;
 comm – коммуникатор.
Выходной параметр – win – окно.
2008
Односторонние обмены
Аннулировать окно можно вызовом подпрограммы:
int MPI_Win_free(MPI_Win *win)
MPI_Win_free(win, ierror)
2008
Односторонние обмены
Три операции одностороннего обмена:
1. MPI_Put – передача данных от отправителя в окно;
2. MPI_Get - передача данных из окна отправителю;
3. MPI_Accumulate – обновление окна получателя.
Это неблокирующие операции.
2008
Односторонние обмены
int MPI_Put(void *origin_addr, int origin_count,
MPI_Datatype origin_datatype, int target_rank, MPI_Aint
target_disp, int target_count, MPI_Datatype target_datatype,
MPI_Win win)
MPI_Put(origin_addr, origin_count, origin_datatype,
target_rank, target_disp, target_count, target_datatype,
win, ierror)
Входные параметры:
 origin_addr – адрес буфера отправки сообщения;
 origin_count – количество элементов в буфере отправки;
 origin_datatype – тип передаваемых данных;
 target_rank – ранг адресата;
 target_disp – смещение от начала окна приёма до буфера приёма;
 target_count – количество принимаемых данных;
 target_datatype – тип принимаемых данных;
 win – окно приёма.
2008
Односторонние обмены
При выполнении этой операции данные размещаются в буфере
приёма по адресу
адрес_окна + смещение × disp_unit
При вызове подпрограммы MPI_Get данные копируются в обратном
направлении – из памяти адресата в память «источника».
2008
Односторонние обмены
Синхронизация при выполнении односторонних обменов
Операции синхронизации:
 MPI_Win_fence
 MPI_Win_start, MPI_Win_complete, MPI_Win_post, MPI_Win_wait
 MPI_Win_lock, MPI_Win_unlock
2008
Односторонние обмены
Пример
subroutine example(vec1, b, map, n, comm, p)
integer n, map(n), comm, p
real vec1(n), b(n)
integer sizeofreal, win, ierr
call MPI_Type_extent(MPI_REAL, sizeofreal, ierr)
call MPI_Win_create(b, n * sizeofreal, sizeofreal, &
MPI_INFO_NULL, comm, win, ierr)
call MPI_Win_fence(0, win, ierr)
do i = 1, n
j = map(i) / p
k = mod(map(i), p)
call MPI_Get(vec1(i), 1, MPI_REAL, j, k, 1, MPI_REAL, win, &
ierr)
end do
call MPI_Win_fence(0, win, ierr)
call MPI_Win_free(win, ierr)
end
2008
Коллективные обмены
2008
Коллективные обмены
В MPI-2 расширены возможности коллективных обменов
сообщениями.
Расширения заключаются в обобщении некоторых операций
коллективного
обмена
на
интеркоммуникаторы,
введении
дополнительных конструкторов интеркоммуникаторов, введении двух
новых операций обмена – обобщённой операции «all-to-all» и
операции исключающего сканирования. Есть и другие расширения.
Подпрограмма MPI_Comm_create может использоваться для создания
интеркоммуникаторов.
2008
Коллективные обмены
2008
Коллективные обмены
Подпрограмма
MPI_Comm_split
расщепления интеркоммуникатора.
может
использоваться
для
В MPI-1 коллективные обмены ограничены интракоммуникаторами.
В MPI-2 коллективные
интеркоммуникаторах.
2008
обмены
могут
выполняться
и
в
Коллективные обмены
Пример. Операция Allgather в интеркоммуникаторе
2008
Коллективные обмены
При выполнении коллективных обменов допускается использование
одного буфера как для передачи, так и для приёма. Только для
интракоммуникаторов!
В MPI-2 имеется обобщённая операция MPI_Alltoallw. Она допускает
дифференцированное задание параметров count, displacement,
datatype. Смещения задаются в байтах.
2008
Внешние интерфейсы
2008
Внешние интерфейсы
Механизм внешних интерфейсов позволяет программисту добавить
новую функциональность поверх базовой функциональности MPI.
Обобщённые запросы дают
неблокирующие операции.
возможность
определить
новые
При использовании стандартных запросов операции, связанные с
ними, выполняются средой исполнения MPI и приложение на этот
процесс не влияет.
При использовании обобщённых запросов «ответственность» за
выполнение операции берёт на себя приложение. Оно сообщает MPI о
завершении операции.
2008
Внешние интерфейсы
Операции с обобщёнными запросами:
 MPI_Grequest_start
 MPI_Grequest_complete
и некоторые другие.
2008
Другие возможности MPI-2
2008
Другие возможности MPI-2
Операции декодирования производных типов.
Ассоциирование пользовательской информации с полями структуры
status.
Присвоение имён объектам MPI (например, коммуникаторам, окнам и
др.).
MPI и многопоточность (MPI_Init_thread, MPI_Thread_single,
MPI_Thread_multiple и др.).
Новые операции кеширования атрибутов.
2008
Другие возможности MPI-2
Параллельные
операции
ввода-вывода
(MPI_File_open,
MPI_File_close, MPI_File_read, MPI_File_write и др.).
2008
Отладка и профилирование
параллельных MPI-программ
2008
Отладка и профилирование
параллельных MPI-программ
Отладка параллельных MPI-программ без использования специальных
программных инструментов сложна и малоэффективна.
Существуют разные инструменты, среди них jumpshot – собственное
средство отладки MPI.
Intel ® Trace Analyzer and Collector – это инструмент анализа, для
которого характерно следующее:
 анализ выполняется на основе статистики, собранной во время
выполнения программы;
 «инструментовка» исполняемого файла почти не влияет на
производительность программы;
 анализ выполняется и для обменов сообщениями;
 поддерживается OpenMP и гибридная модель параллельного
программирования MPI+OpenMP;
 поддерживается многопоточность Java.
2008
Отладка и профилирование
параллельных MPI-программ
Интерфейс программы
2008
Отладка и профилирование
параллельных MPI-программ
Так выглядит «плохая» программа (блокирующие обмены):
2008
Отладка и профилирование
параллельных MPI-программ
Так выглядит «хорошая» программа (неблокирующие обмены):
2008
Заключение
В этой лекции мы рассмотрели:
 атрибуты;
 операции одностороннего обмена;
 внешние интерфейсы;
 обобщённые коллективные обмены;
 другие возможности MPI-2;
 некоторые инструменты отладки и настройки MPI-приложений.
2008
Задания для самостоятельной работы
Решения следует высылать по электронной почте:
parallel-g112@yandex.ru
2008
Задания для самостоятельной работы
Повторите задания предыдущих лекций, используя там, где это
возможно, операции одностороннего обмена, расширенную
функциональность коллективных обменов MPI-2, другие возможности
MPI-2.
2008
Download