Примеры распределения работы между процессами
Семинар 2.
Тема: Технология MPI: функции для определения номера процесса и размера группы; распределение работы между процессами
План:
· Введение
· Функции для определения номера процесса и размера группы
· Примеры распределения работы между процессами
· Задания
Введение
Как уже обсуждали – технология MPI подразумевает модель распределенной памяти, независимо от того, на какой реальной архитектуре проводится расчет.
Это означает, в частности, что любая объявленная переменная появляется в локальной памяти каждого процесса, задействованного для решения данной задачи.
При этом каждый задействованный процесс, независимо от остальных процессов в группе, выполняет все операции в программе – но надо своими собственными данными, расположенными в локальной памяти.
Таким образом, если не предпринимать специальных усилий – каждый процесс выполнит все операции в программе. Мы это видели на примере простейшей программы «HELLO».
В реальных задачах нам требуется не дублировать многократное выполнение кода всеми процессами, а организовать работу так, чтобы каждый процесс выполнял свой «кусочек» работы, чтобы эти кусочки не перекрывались (или перекрывались по минимуму), и чтобы в совокупности вся необходимая работа, ради которой составляли программу – оказалась выполнена.
За счет того, что каждому процессу достается выполнить не всю работу, а только ее часть – можно ожидать уменьшения времени счета при использовании более чем одного процесса. Это называется ускорением вычислений.
|
|
Конечно же эффект будет виден на достаточно сложных ресурсоемких программах. Наша же задача – научиться, на простейших примерах, корректно распределять работу между процессами с использованием MPI-функций.
Для того, чтобы «сказать» каждому процессу, что именно ему надо делать – нужно каким-то образом идентифицировать их. В MPI процессы идентифицируются по номерам. Нумерация процессов и определение внутри программы их количества осуществляются вызовом соответствующих функций.
Функции для определения номера процесса и размера группы
Как уже сказано, по умолчанию система создает группу процессов, количество которых равно числу запрашиваемых при запуске, и создает коммуникатор MPI_COMM_WORLD, объединяющий все задействованные процессы.
Каждый процесс, состоящий в группе, может запросить свой порядковый номер в этой группе и общее число процессов в данной группе.
Запрос порядкового номера производится посредством обращения к функции:
int MPI_Comm_rank (MPI_Comm comm, int *rank)
В качестве параметров функция принимает имя коммуникатора группы, в которой состоит процесс, и указатель на целочисленную переменную, которой будет присвоен порядковый номер процесса.
|
|
Запрос количества процессов в группе (это обычно называют «размер группы») происходит по аналогичной схеме. За это отвечает функция
int MPI_Comm_size (MPI_Comm comm, int *size)
Параметры данной функции аналогичны параметрам функции MPI_Comm_rank – имя коммуникатора группы и указатель на целочисленную переменную, которой будет присвоено число процессов.
Пример
Программа, в которой каждый MPI-процесс определяет свой порядковый номер и число процессов в группе и выводит на экран эти значения.
Здесь каждый процесс в своей локальной памяти объявляет целые переменные для записи номера процесса и количества процессов в группе.
int myid, numprocs;
Каждый процесс вызывает функции
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
В результате по адресу myid в каждом процессе записывается его номер, в по адресу numprocs – количество процессов.
Далее каждые процесс печатает вои собственные переменные myid, numprocs.
Номер процесса (myid) у каждого свой, нумерация идет от 0, при печати порядок номеров может нарушаться, поскольку процессы работают параллельно и необязательно процесс, скажем, с номером 0 успеет первым напечатать свои данные.
|
|
Переменная numprocs – также у каждого процесса своя, но ее значения во всех процессах совпадают:
Отметим, что в MPI существует целый набор функций для организации подгрупп в рамках имеющейся группы и для создания коммуникаторов. Поэтому вышеописанных двух функциях и во всех остальных функциях в качестве параметра фигурирует имя коммуникатора группы.
Примеры распределения работы между процессами
В рассмотренном примере, как и в примере на прошлом семинаре – каждый процесс выполнил все операции в программе.
Рассмотрим, как, зная номер процесса и их общее количество, можно распределить работу между параллельными процессами, тем или иным образом явно указав, какие именно фрагменты кода выполняются процессами с определенными номерами. Простейший вариант – использование условного оператора if.
Модифицируем предыдущий пример:
Здесь каждый процесс печатает свой номер, а количество процессов (размер группы) печатает только процесс с номером 0. Также, процесс, имеющий максимальный номер – печатает «HELLO».
Отметим, что максимальный номер – на 1 меньше размера группы, поскольку нумерация процессов осуществляется с 0.
|
|
Как видим, теперь разные процессы выполнили различные действия.
Рассмотрим теперь более общий пример – как можно в общем виде, без использования оператора if осуществить распараллеливание цикла, в котором на каждой итерации значение целочисленной переменной А=0 увеличивается на 1.
Один из вариантов – «блочное» распределение расчета между параллельными процессами. Поставим задачу написать программу в общем виде, чтобы схема распределения работала при любом количестве процессов, не превышающем размерность массива.
В предположении известной конечной длины цикла и известного количества процессов можно вычислить размер блока, предназначенного для обработки каждым процессом и позиции начального и конечного элементов массива.
Пусть мы в нашем цикле N итераций и мы имеем np параллельных MPI-процессов. Для распределения итераций цикла между задействованными процессами необходимо узнать размер блока (delta) итераций, выполняемого каждым процессом, а также начальный и конечный индексы этих блоков.
Пусть номер процесса хранится в переменной rank, начальные и конечные индексы блоков – в imin и imax соответственно.
КОЛИЧЕСТВО ИТЕРАЦИЙ В ЦИКЛЕ
Здесь ost – остаток, который назначается в работу процессу с максимальным номером, в случае, когда N не делится нацело на np.
При N=20 и np=4 каждый процесс с номером rank выполняет по del=N/np итераций, при этом переменная А в каждом процессе «пробегает» значения от 1 до del=5.
При запуске программы с другим количеством процессов переменная А в каждом процессе будет «пробегать» значения от 1 до del=N/np, за исключением последнего процесса, где А будет увеличиваться от 1 до del=N/np+ost. Предлагаем убедиться в этом самостоятельно.
Задания:
1. Изучить в учебном пособии по MPI разделы 2.1-2.3 Главы 2.
2. Воспроизвести на кластере HybriLIT рассмотренные примеры.
3. Составить и запустить программу, в которой процесс с номером 0 печатает слово «Hello», процесс с номером 1 печатает слово «Goodbye», процесс с номером 2 печатает количество процессов в группе, каждый процесс с номерами >2 печатают свои номер. Запустить программу с количеством процессов 1,2,3,4,5, объяснить результат, который видим на экране.
Дата добавления: 2021-04-05; просмотров: 277; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!