Обмен данными с использованием MPI. Работа с библиотекой MPI на примере Intel® MPI Library
Запуск MPI-приложения на вычислительном кластере возможен только через систему пакетной обработки заданий. Для упрощения запуска и постановки в очередь параллельной программы предусмотрен специальный скрипт mpirun. Например, mpirun -np 20 ./first.exe запустит параллельную программу first.exe на 20 процессорах, т.е. на 5 узлах. (Каждый узел имеет 2 двуядерных процессора). Стоит обратить внимание, что для запуска исполняемого модуля находящего в текущей директории ($pwd) необходимо явно указать путь «./» Ряд реализаций MPI-1 предоставляет команду запуска для программ MPI, которая имеет форму mpirun <аргументы mpirun><программа><аргументы программы>
Отделение команды запуска программы от самой программы обеспечивает гибкость, особенно для сетевых и гетерогенных реализаций. Наличие стандартного механизма запуска также расширяет мобильность MPI программ на один шаг вперед, к командным строкам и сценариям, которые управляют ими. Например, сценарий набора программ проверки правильности, который выполняет сотни программ, может быть переносимым сценарием, если он написан с использованием такого стандартного механизма запуска. Чтобы не перепутать ``стандартную"" команду с существующей на практике, которая не является стандартной и не переносимой среди реализаций, вместо mpirun MPI определил mpiexec.
В то время как стандартизированный механизм запуска улучшает применимость MPI, диапазон сред настолько разнообразен (например, не может даже быть интерфейса командной строки), что MPI не может принять под мандат такой механизм. Вместо этого, MPI определяет команду запуска mpiexec и рекомендует, но не требует, как совет разработчикам. Однако, если реализация обеспечивает команду называемую mpiexec, она должна иметь форму, описанную ниже: mpiexec -n
будет по крайней мере один способ запустить <программу> с начальным MPI_COMM_WORLD, чья группа содержит
Пример 4.1 Запуск 16 экземпляров myprog на текущей или заданной по умолчанию машине:
mpiexec -n 16 myprog
3. Напишите программу параллельного вычисления определенного интеграла от функции 2*(x+2*x*x/1200.0) в интервале .
Метод левых прямоугольников
double f(double x)
{return 2*(x+2*x*x/1200);} // iskomyi integral
int main(int argc,char **argv)
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
int n=1000,i,d; // 1000 - uzly
float a=0, b=1, h=(b-a)/n,s=0,r=0; //a i b -nachalo i konec otrezka
if (rank!=size-1) // schitaut vse processy, krome poslednego
{ for (i=rank*d; i<(rank+1)*d; i++) { s=s+h*f(a+i*h); }
MPI_Send(&s,1,MPI_FLOAT,size-1,1,MPI_COMM_WORLD);}
{ for (i=0; i { MPI_Recv(&s,1,MPI_FLOAT,i,1,MPI_COMM_WORLD, &status); r+=s; } } MPI_Finalize();} Сурак
1. Shared & distributed memory архитектуралары.
Распределенная общая память (DSM - Distributed Shared Memory) Традиционно распределенные вычисления базируются на модели передачи сообщений, в которой данные передаются от процессора к процессору в виде сообщений. Удаленный вызов процедур фактически является той же самой моделью (или очень близкой). DSM - виртуальное адресное пространство, разделяемое всеми узлами (процессорами) распределенной системы. Программы получают доступ к данным в DSM примерно так же, как они работают с данными в виртуальной памяти традиционных ЭВМ. В системах с DSM данные перемещаются между локальными памятями разных компьютеров аналогично тому, как они перемещаются между оперативной и внешней памятью одного компьютера. Конфигурация - с распределенной разделяемой памятью, представляет собой вариант распределенной памяти. Здесь все узлы, состоящие из одного или нескольких процессоров, подключенных по схеме SMP, используют общее адресное пространство. Отличие этой конфигурации от машины с распределенной памятью в том, что здесь любой процессор может обратиться к любому участку памяти. Однако, время обращения к разным участкам памяти для каждого процессора различно в зависимости от того, где участок физически расположен в кластере. По этой причине такие конфигурации еще называют машинами с неоднородным доступом к памяти NUMA (non-uniform memory access). Отличия MPI и PVM.
Система PVM (Parallel Virtual Machine) была создана для объединения нескольких связанных сетью рабочих станций в единую виртуальную параллельную вычислительную машину. Система представляет собой надстройку над операционной системой UNIX и используется на различных аппаратных платформах, включая и системы с массовым параллелизмом. Наиболее распространены сейчас системы параллельного программирования на основе MPI (Message Parsing Interface). Идея MPI исходно проста и очевидна. Она предполагает представление параллельной программы в виде множества параллельно исполняющихся процессов, взаимодействующих друг с другом в ходе исполнения передачи данных с помощью коммуникационных процедур. Они и составляют библиотеку MPI. Однако надлежащая реализация MPI для обеспечения межпроцессорных коммуникаций оказалась довольно сложной. Такая сложность связана с необходимостью достижения высокой производительности программ, необходимостью использовать многочисленные ресурсы мультикомпьютера, и, как следствие большим разнообразием в реализации коммуникационных процедур в зависимости от режима обработки данных. В этой заметке показано как установить MPI, подключить его к Visual Studio, а затем использовать с заданными параметрами (числом вычислительных узлов). В статье используется Visual Studio 2015, т.к. именно с ней возникали проблемы у моих студентов (эта заметка написана студентами для студентов), однако вероятно инструкция подойдет и для других версий. Шаг 1:
Шаг 2:
“C:\Program Files\Microsoft HPC Pack 2008 SDK\Include”
В поле Library Directories: “C:\Program Files\Microsoft HPC Pack 2008 SDK\Lib\amd64”
В поле с библиотеками, если стоит 32 разрядная версия, вместо amd64 нужно прописать i386. Msmpi.lib
: Шаг 3
: Для настройки запуска необходимо перейти во вкладку Debugging и в поле Command указать: “C:\Program Files\Microsoft HPC Pack 2008 SDK\Bin\mpiexec.exe”
В поле Command Arguments указать, например, N 4 $(TargetPath)
Число 4 указывает на количество процессов. Для запуска программы необходимо подключить библиотеку Путь к проекту не должен содержать кириллицу. При возникновении ошибок можно воспользоваться Microsoft MPI, доступный по на сайте Microsoft. Для этого после установки достаточно прописать в поле Command вкладки Debugging путь: “C:\Program Files\Microsoft MPI\Bin\mpiexec.exe” Также перед запуском программы не забудьте указать её разрядность: Пример запуска программы с MPI
: #include Работа программы на 2 узлах: Аннотация:
Лекция посвящена рассмотрению технологии MPI как стандарта параллельного программирования для систем с распределенной памятью. Рассматриваются основные режимы передачи данных. Вводятся такие понятия, как группы процессов и коммуникаторы. Рассматриваются основные типы данных, операции "точка-точка", коллективные операции, операции синхронизации и измерения времени.
Цель лекции:
Лекция направлена на изучение общей методики разработки параллельных алгоритмов. Видеозапись лекции - (объем - 134 МБ). Рассмотрим ряд понятий и определений, являющихся основополагающими для стандарта MPI
. Под параллельной программой
в рамках MPI понимается множество одновременно выполняемых процессов
. Процессы могут выполняться на разных процессорах, но на одном процессоре могут располагаться и несколько процессов (в этом случае их исполнение осуществляется в режиме разделения времени). В предельном случае для выполнения параллельной программы может использоваться один процессор – как правило, такой способ применяется для начальной проверки правильности параллельной программы. Каждый процесс параллельной программы порождается на основе копии одного и того же программного кода (модель SPMP
). Данный программный код, представленный в виде исполняемой программы, должен быть доступен в момент запуска параллельной программы на всех используемых процессорах. Исходный программный код для исполняемой программы разрабатывается на алгоритмических языках C или Fortran с использованием той или иной реализации библиотеки MPI. Количество процессов и число используемых процессоров определяется в момент запуска параллельной программы средствами среды исполнения MPI-программ и в ходе вычислений меняться не может (в стандарте MPI-2 предусматривается возможность динамического изменения количества процессов). Все процессы программы последовательно перенумерованы от 0 до p-1
, где p
есть общее количество процессов. Номер процесса именуется рангом
процесса. Основу MPI составляют операции передачи сообщений. Среди предусмотренных в составе MPI функций различаются парные
(point-to-point
) операции между двумя процессами и коллективные
(collective
) коммуникационные действия для одновременного взаимодействия нескольких процессов. Для выполнения парных операций могут использоваться разные режимы передачи, среди которых синхронный, блокирующий и др. – полное рассмотрение возможных режимов передачи
будет выполнено в подразделе 5.3. Как уже отмечалось ранее, стандарт MPI предусматривает необходимость реализации большинства основных коллективных операций передачи данных – см. подразделы 5.2 и 5.4. Процессы параллельной программы объединяются в группы
. Под коммуникатором
в MPI понимается специально создаваемый служебный объект, объединяющий в своем составе группу процессов и ряд дополнительных параметров (контекст
), используемых при выполнении операций передачи данных. Как правило, парные операции передачи данных выполняются для процессов, принадлежащих одному и тому же коммуникатору. Коллективные операции применяются одновременно для всех процессов коммуникатора. Как результат, указание используемого коммуникатора является обязательным для операций передачи данных в MPI. В ходе вычислений могут создаваться новые и удаляться существующие группы процессов и коммуникаторы. Один и тот же процесс может принадлежать разным группам и коммуникаторам. Все имеющиеся в параллельной программе процессы входят в состав создаваемого по умолчанию коммуникатора с идентификатором MPI_COMM_WORLD. При необходимости передачи данных между процессами из разных групп необходимо создавать глобальный коммуникатор (intercommunicator
). Подробное рассмотрение возможностей MPI для работы с группами и коммуникаторами будет выполнено в подразделе 5.6. При выполнении операций передачи сообщений для указания передаваемых или получаемых данных в функциях MPI необходимо указывать тип
пересылаемых данных. MPI содержит большой набор базовых типов
данных, во многом совпадающих с типами данных в алгоритмических языках C и Fortran. Кроме того, в MPI имеются возможности для создания новых производных типов
данных для более точного и краткого описания содержимого пересылаемых сообщений. Подробное рассмотрение возможностей MPI для работы с производными типами данных будет выполнено в подразделе 5.5. Как уже отмечалось ранее, парные операции передачи данных могут быть выполнены между любыми процессами одного и того же коммуникатора, а в коллективной операции принимают участие все процессы коммуникатора. В этом плане, логическая топология линий связи между процессами имеет структуру полного графа (независимо от наличия реальных физических каналов связи между процессорами). Вместе с этим (и это уже отмечалось в разделе 3), для изложения и последующего анализа ряда параллельных алгоритмов целесообразно логическое представление имеющейся коммуникационной сети в виде тех или иных топологий. В MPI имеется возможность представления множества процессов в виде решетки
произвольной размерности (см. подраздел 5.7). При этом, граничные процессы решеток могут быть объявлены соседними и, тем самым, на основе решеток могут быть определены структуры типа тор
. Кроме того, в MPI имеются средства и для формирования логических (виртуальных) топологий любого требуемого типа. Подробное рассмотрение возможностей MPI для работы с топологиями будет выполнено в подразделе 5.7. И, наконец, последний ряд замечаний перед началом рассмотрения MPI: Приступая к изучению MPI, можно отметить, что, с одной стороны, MPI достаточно сложен – в стандарте MPI предусматривается наличие более 125 функций. С другой стороны, структура MPI является тщательно продуманной – разработка параллельных программ может быть начата уже после рассмотрения всего лишь 6 функций MPI. Все дополнительные возможности MPI могут осваиваться по мере роста сложности разрабатываемых алгоритмов и программ. Именное в таком стиле – от простого к сложному – и будет далее представлен весь учебный материал по MPI. Приведем минимально-необходимый набор функций MPI, достаточный для разработки достаточно простых параллельных программ. Первой вызываемой функцией
MPI должна быть функция: int MPI_Init (int *agrc, char ***argv); для инициализации среды выполнения MPI-программы. Параметрами функции являются количество аргументов в командной строке и текст самой командной строки. Последней вызываемой функцией
MPI обязательно должна являться функция: int MPI_Finalize (void); Как результат, можно отметить, что структура параллельной программы, разработанная с использованием MPI, должна иметь следующий вид: #include "mpi.h"
int main (int argc, char *argv) {
<программный код без использования MPI функций>
MPI_Init (&agrc, &argv);
<программный код с использованием MPI функций>
MPI_Finalize();
<программный код без использования MPI функций>
return 0;
} Следует отметить: Рассмотренные примеры функций дают представление синтаксиса именования функций в MPI. Имени функции предшествует префикс MPI, далее следует одно или несколько слов названия, первое слово в имени функции начинается с заглавного символа, слова разделяются знаком подчеркивания. Названия функций MPI, как правило, поясняют назначение выполняемых функцией действий. Следует отметить: Наиболее распространенной технологией программирования для параллельных систем с распределенной памятью в настоящее время является MPI (Message Passing Interface). Основным способом взаимодействия параллельных процессов друг с другом в таких системах является передача сообщений (Message Passing). По сути MPI – это библиотека и среда исполнения для параллельных программ на языках C или Fortran. В данном пособии будут описаны примеры программ на языке С. Изначально MPI позволяет использовать модель программирования MIMD (Multiple Instruction Multiple Data) – много потоков инструкций и данных, т.е. объединение различных программ с различными данными. Но программирование для такой модели на практике оказывается слишком сложным, поэтому обычно используется модель SIMD (Single Program Multiple Data) –одна программа и много потоков данных. Здесь параллельная программа пишется так, чтобы разные ее части могли одновременно выполнять свою часть задачи, таким образом, достигается параллелизм. Поскольку все функции MPI содержаться в библиотеке, то при компиляции параллельной программы необходимо будет прилинковать соответствующие модули. Под параллельной программой в рамках MPI понимается множество одновременно выполняемых процессов. Процессы могут выполняться на разных процессорах, но на одном процессоре могут располагаться и несколько процессов (в этом случае их исполнение осуществляется в режиме разделения времени). При запуске MPI – программы на кластере на каждом из его узлов будет выполняться своя копия программы, выполняющая свою часть задачи, из этого следует, что параллельная программа – это множество взаимодействующих процессов, каждый из которых работает в своем адресном пространстве. В предельном случае для выполнения параллельной программы может использоваться один процессор - как правило, такой способ применяется для начальной проверки правильности параллельной программы. Количество процессов и число используемых процессоров определяется в момент запуска параллельной программы средствами среды исполнения MPI - программ и в ходе вычислений меняться не может. Все процессы программы последовательно перенумерованы от 0 до np-1, где np есть общее количество процессов. Номер процесса называется рангом процесса. Взаимодействуют параллельные процессы между собой при помощи посылки сообщений. Методы посылки (их называют коммуникации) бывают двух видов – коллективные(collective) и “точка-точка” (point-to-point). При коллективных коммуникациях процесс посылает нужную информацию одновременно целой группе процессов, еще есть более общий случай, когда внутри группы процессов передача информации идет от каждого процесса к каждому. Более простыми коммуникациями являются коммуникации типа ”точка-точка”, когда один процесс посылает информацию второму или они оба обмениваются информацией. Функции коммуникаций – основные функции библиотеки MPI. Кроме этого, обязательными функциями являются функции инициализации и завершения MPI – MPI_Init и MPI_Finalize. MPI_Init должна вызываться в самом начале программ, а MPI_Finalize – в самом конце. Все остальные функции MPI должны вызываться между этими двумя функциями. Как процесс узнает о том, какую часть вычислений он должен выполнять? Каждый процесс, исполняющийся на кластере, имеет свой уникальный номер – ранг. Когда процесс узнает свой ранг и общее количество процессов, он может определить свою часть работы. Для этого в MPI существуют специальные функции – MPI_Comm_rank и MPI_Comm_size. MPI_Comm_rank возвращает целое число - ранг процесса, вызвавшего ее, а MPI_Comm_size возвращает общее число работающих процессов. Процессы отлаживаемой параллельной программы пользователя объединяются в группы. Под коммуникатором в MPI понимается специально создаваемый служебный объект, объединяющий в своем составе группу процессов и ряд дополнительных параметров (контекст), используемых при выполнении операций передачи данных. Коммуникатор, автоматически создаваемый при запуске программы и включающий в себя все процессы на кластере, называется MPI_COMM_WORLD. В ходе вычислений могут создаваться новые и удаляться существующие группы процессов и коммуникаторы. Один и тот же процесс может принадлежать разным группам и коммуникаторам. Коллективные операции применяются одновременно для всех процессов коммуникатора, поэтому для них одним из параметров всегда будет выступать коммуникатор. При выполнении операций передачи сообщений в функциях MPI необходимо указывать тип пересылаемых данных. MPI содержит большой набор базовых типов данных, основанных на стандартных типах данных языка С. Кроме того, программист может конструировать свои типы данных при помощи специальных функций MPI. Ниже приведена таблица соответствия для базовых типов данных. Пример запуска библиотеки MPI: логин student, пароль s304. #include #include int main (int argc, char *argv) /* Инициализация MPI */ MPI_Init (&argc, &argv); /* получение ранга процесса */ MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* получение общего числа процессов */ MPI_Comm_size (MPI_COMM_WORLD, &size); printf("Hello world from process %d of %d\n", rank, size); /* завершение MPI */ Для компиляции используется компилятор и линковщик. Командная строка mpicc.
(см. mpicc….- help)
Каждый из запущенных процессов должен вывести на экран свой ранг и общее число процессов. Попробуем откомпилировать и запустить эту программу. $ mpicc hello.c –o hello.o
$ mpicc hello.o –o hello
Файл hello и будет исполняемым файлом примера. Можно запустить его на одной машине и посмотреть, что число процессоров будет равно 1, а ранг процесса 0: $ ./hello
Hello world from process 0 of 1
При работе на сервере для запуска используется команда mpirun
. У нее есть два основных аргумента – имя файла, содержащего адреса узлов и число узлов, на котором будет запущена программа. $ mpirun n0-6 –v hosts hello
Hello world from process 0 of 7
Hello world from process 3 of 7
Hello world from process 5 of 7
Hello world from process 4 of 7
Hello world from process 2 of 7
Hello world from process 6 of 7
Hello world from process 1 of 7
Программа будет запущена на 7 узлах (включая сервер), а адреса этих узлов находятся в файле hosts.
Печать на экран осуществлялась процессами не по порядку их рангов. Это связано с тем, что запуск процессов не синхронизирован, однако в MPI существуют специальные функции для синхронизации процессов. Простейшая программа не содержит функций передачи сообщений. В реальных же задачах процессам требуется взаимодействовать друг с другом. Естественно, на передачу сообщений тратится время, что снижает коэффициент распараллеливания задачи. Чем выше скорость интерфейса передачи сообщений (например Ethernet 10Mb/sec и Gigabit Ethernet), тем меньше будут затраты на передачу данных. Т.к. время обмена данными между процессами намного (на порядки) больше времени доступа к собственной памяти, распределение работы между процессами должно быть ‘крупнозернистым’, нужно избегать ненужных пересылок данных. Среди задач численного анализа встречается немало задач, распараллеливание которых очевидно. Например, численное интегрирование сводится фактически к (многочисленному) вычислению подинтегральной функции (что естественно доверить отдельным процессам), при этом главный процесс управляет процессом вычислений (определяет стратегию распределения точек интегрирования по процессам и собирает частичные суммы). Подобным же распараллеливанием обладают задачи поиска и сортировки в линейном списке, численного нахождения корней функций, поиск экстремумов функции многих переменных, вычисление рядов и другие. В этой лабораторной работе мы рассмотрим два параллельных алгоритма вычисления числа π. Вычисление числа π методом численного интегрирования
Известно, что Заменяя вычисление интеграла конечным суммированием, имеем , где , n-число участков суммирования при численном интегрировании. Площадь каждого участка вычисляется как произведение ширины ‘полоски’ на значение функции в центре ‘полоски’, далее площади суммируются главным процессом (используется равномерная сетка). Очевидно, что распараллеливание этой задачи легко сделать, если каждый процесс будет считать свою частичную сумму, а затем передаст результат вычислений главному процессу. Как избежать здесь повторяющихся вычислений? Процесс должен знать свой ранг, общее число процессов и число интервалов, на которое будет разбит отрезок (чем больше интервалов, тем выше будет точность). Тогда в цикле от 1 до числа интервалов процесс будет вычислять площадь полоски на i-ом интервале, а затем переходить не на следующий i+1интевал, а на интервал i+m, где m-число процессов. Как мы уже знаем, для получения ранга и общего числа процессов существуют функции MPI_Comm_rank
и MPI_Comm_size
. Перед началом вычислений главный процесс должен передать всем остальным число интервалов, а после вычислений собрать у них полученные частичные суммы и просуммировать их, в MPI это реализуется передачей сообщений. Для передачи сообщений здесь удобно использовать функцию коллективного взаимодействия MPI_Bcast
, которая рассылает одинаковые данные от одного процесса всем остальным. Для сбора частичных сумм есть 2 варианта - можно использовать MPI_Gather
, которая собирает данные со всех процессов и отдает их одному (получается массив из m элеменов, где m-число процессов) или MPI_Reduce
. MPI_Reduce
действует аналогично MPI_Gather
– собирает данные от всех процессов и отдает одному, но не в виде массива, а предварительно производит определенную операцию между элементами массива, например, суммирование и после этого отдает один элемент. Для этой задачи более удобным выглядит использование MPI_Reduce
. Текст программы приведен ниже #include "mpi.h" #include #include double f(double a) return (4.0 / (1.0 + a*a)); int main(int argc, char *argv) int n, myid, numprocs, i; double PI25DT = 3.141592653589793238462643; double mypi, pi, h, sum, x; double startwtime, endwtime; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&numprocs); MPI_Comm_rank(MPI_COMM_WORLD,&myid); startwtime = MPI_Wtime(); MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); h = 1.0 / (double) n; for (i = myid + 1; i <= n; i += numprocs) x = h * ((double)i - 0.5); MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); printf("pi is approximately %.16f, Error is %.16f\n", pi, fabs(pi - PI25DT)); endwtime = MPI_Wtime(); printf("wall clock time = %f\n", endwtime-startwtime); Рассмотрим подробнее вызовы функий MPI_Bcast
и MPI_Reduce
: MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD) – содержимое переменной n и одного элемента типа MPI_INT из процесса с рангом 0 посылается всем остальным процессам (MPI_COMM_WORLD – все процессы в коммуникаторе) в ту же переменную n. После этого вызова каждый процесс будет знать общее число интервалов. По окончании вычислений MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD) суммирует (параметр MPI_SUM) значения из переменных mypi типа MPI_DOUBLE каждого процесса и записывает результат в переменную pi процесса с рангом 0. Для замера времени вычислений главный процесс использует функцию MPI_Wtime. double MPI_Wtime();
MPI_Wtime
возвращает число секунд в формате числа с плавающей точкой, представляющее время, прошедшее с момента старта программы. Вычисление числа π методом Монте-Карло
Для вычисления значения πможно использовать метод ‘стрельбы’. В применении к данному случаю метод заключается в генерации равномерно распределенныхна двумерной области точек и определении . Вычисленное таким образом значение π является приближенным, в общем случае точность вычисления искомого значения повышается с увеличением числа ‘выстрелов’ и качества генетатора случайных чисел; подобные методы используются в случае трудностей точной числовой оценки. Параллельный алгоритм вычисления числа π данным методом во многом похож на предыдущий рассмотренный нами алгоритм. Для генерации случайных чисел нужно использовать функцию srand, которой в качестве агрумента (семени последовательности) задавать ранг процесса, таким образов, у каждого процесса будет своя последовательность. #include void srand(unsigned seed);
Функция srand() устанавливает исходное число для последовательности, генерируемой функцией rand(). #include int rand(void);
Функция rand() генерирует последовательность псевдослучайных чисел. При каждом обращении к функции возвращается целое в интервале между нулем и значением RAND_MAX. Для сбора результата здесь также удобно использовать MPI_Reduce с заданием операции суммирования (MPI_SUM), затем разделить полученную сумму на число процессоров, получив среднее арифметическое. int MPI_Reduce(void* sendbuf, void* recvbuf, int count,
MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);
Параметры:
sendbuf адрес посылающего буфера
recvbuf адрес принимающего буфера
op операция редукции
comm коммуникатор
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root,
MPI_Comm comm);
Параметры:
buffer адрес посылающего/принимающего буфера
count количество элементов в посылающем буфере (целое)
datatype тип данных элементов посылающего буфера
root номер главного процесса (целое)
comm коммуникатор
Задание
: в соответствии с номером варианта откомпилировать и запустить параллельную программы, вычисляющую число π по заданному алгоритму. Запустить задачу на одном узле и с кластера, на заданном количестве узлов. Оценить время выполнения вычислений, точность и коэффициент распараллеливания Амдала с учетом сетевой задержки теоретически и по результатам выполнения работы. Варианты заданий · Постановка задачи, вариант. · Текст параллельной программы на языке С согласно заданию. · Результаты запуска программы на одном узле, время выполнения t i , результат вычислений, ошибка. · Результаты запуска программы на сервере, время выполнения, результат вычислений, ошибка. · Описать параллельный алгоритм, информационные потоки при выполнении программы и загрузку КЭШ-памяти узлов. Вычислить по результатам работы программы коэффициент Амдала - К j . · Учитывая результаты работы группы студентов, построить гистограмму зависимости К j , t i от количества процессоров участвующих в вычислениях. В этом посте мы расскажем об организации обмена данными с помощью MPI на примере библиотеки Intel MPI Library. Думаем, что эта информация будет интересна любому, кто хочет познакомиться с областью параллельных высокопроизводительных вычислений на практике. Мы приведем краткое описание того, как организован обмен данными в параллельных приложениях на основе MPI, а также ссылки на внешние источники с более подробным описанием. В практической части вы найдете описание всех этапов разработки демонстрационного MPI-приложения «Hello World», начиная с настройки необходимого окружения и заканчивая запуском самой программы. MPI является наиболее распространенным стандартом интерфейса передачи данных в параллельном программировании. Стандартизацией MPI занимается MPI Forum . Существуют реализации MPI под большинство современных платформ, операционных систем и языков. MPI широко применяется при решении различных задач вычислительной физики, фармацевтики, материаловедения, генетики и других областей знаний. Параллельная программа с точки зрения MPI - это набор процессов, запущенных на разных вычислительных узлах. Каждый процесс порождается на основе одного и того же программного кода. Основная операция в MPI - это передача сообщений. В MPI реализованы практически все основные коммуникационные шаблоны: двухточечные (point-to-point), коллективные (collective) и односторонние (one-sided). Для демонстрации я выбрал сервис Amazon Elastic Compute Cloud (Amazon EC2). Новым пользователям Amazon предоставляет пробный год бесплатного использования серверами начального уровня. Работа с Amazon EC2 интуитивно понятна. В случае возникновения вопросов, можно обратиться к подробной документации (на англ.). При желании можно использовать любой другой аналогичный сервис. Создаем два рабочих виртуальных сервера. В консоли управления выбираем EC2 Virtual Servers in the Cloud
, затем Launch Instance
(под «Instance» подразумевается экземпляр виртуального сервера). Следующим шагом выбираем операционную систему. Intel MPI Library поддерживает как Linux, так и Windows. Для первого знакомства с MPI выберем OC Linux. Выбираем Red Hat Enterprise Linux 6.6 64-bit
или SLES11.3/12.0
. После того, как сервис предложит нам запустить Launch Instances
(настроенные виртуальные сервера), сохраняем SSH-ключи, которые понадобятся для связи с виртуальными серверами извне. Состояние виртуальных серверов и IP адреса для связи с серверами локального компьютера можно отслеживать в консоли управления. Важный момент: в настройках Network & Security / Security Groups
необходимо создать правило, которым мы откроем порты для TCP соединений, - это нужно для менеджера MPI-процессов. Правило может выглядеть так: И, напоследок, небольшой опрос по поводу возможных тем для будущих публикаций, посвященных высокопроизводительным вычислениям. Только зарегистрированные пользователи могут участвовать в опросе. , пожалуйста.
Необходимо установить пакет HPC Pack 2008 SDK SP2 (в вашем случае может быть уже другая версия), доступный на официальном сайте Microsoft. Разрядность пакета и системы должны соответствовать.
Необходимо настроить пути, для этого переходим во вкладку Debug — Properties:5.1. MPI: основные понятия и определения
5.1.1. Понятие параллельной программы
5.1.2. Операции передачи данных
5.1.3. Понятие коммуникаторов
5.1.4. Типы данных
5.1.5. Виртуальные топологии
5.2. Введение в разработку параллельных программ с использованием MPI
5.2.1. Основы MPI
5.2.1.1 Инициализация и завершение MPI программ
Основные функции MPI
Константы MPI
ТИП данных языка С
MPI_INT
signed int
MPI_UNSIGNED
unsigned int
MPI_SHORT
signed int
MPI_LONG
signed long int
MPI_UNSIGNED_SHORT
unsigned int
MPI_UNSIGNED_LONG
unsigned long int
MPI_FLOAT
float
MPI_DOUBLE
double
MPI_LONG_DOUBLE
long double
MPI_UNSIGNED_CHAR
unsigned char
MPI_CHAR
signed char
№ Варианта
Алгоритм
Число процессоров
Число итераций на каждом процессоре
Численное интегрирование
Монте-Карло
Численное интегрирование
Монте-Карло
Численное интегрирование
Монте-Карло
Численное интегрирование
Монте-Карло
Численное интегрирование
Монте-Карло
Численное интегрирование
Монте-Карло
Численное интегрирование
Монте-Карло
Численное интегрирование
Монте-Карло
Численное интегрирование
Монте-Карло
Численное интегрирование
Монте-Карло
MPI (Message Passing Interface)
MPI - интерфейс передачи сообщений между процессами, выполняющими одну задачу. Он предназначен, в первую очередь, для систем с распределенной памятью (MPP) в отличие от, например, OpenMP . Распределенная (кластерная) система, как правило, представляет собой набор вычислительных узлов, соединенных высокопроизводительными каналами связи (например, InfiniBand).Работа с MPI
Рассмотрим на живом примере, как устроена типичная MPI-программа. В качестве демонстрационного приложения возьмем исходный код примера, поставляемого с библиотекой Intel MPI Library. Прежде чем запустить нашу первую MPI-программу, необходимо подготовить и настроить рабочую среду для экспериментов.Настройка кластерного окружения
Для экспериментов нам понадобится пара вычислительный узлов (желательно со схожими характеристиками). Если под руками нет двух серверов, всегда можно воспользоваться cloud-сервисами.
Выбираем Instance Type
(тип сервера). Для экспериментов нам подойдет t2.micro (1 vCPUs, 2.5 GHz, Intel Xeon processor family, 1 GiB оперативной памяти). Как недавно зарегистрировавшемуся пользователю, мне такой тип можно было использовать бесплатно - пометка «Free tier eligible». Задаем Number of instances
: 2 (количество виртуальных серверов).Type: Custom TCP Rule
Protocol: TCP
Port Range: 1024-65535
Source: 0.0.0.0/0
В целях безопасности можно задать и более строгое правило, но для нашего демонстрационного примера достаточно этого.