Примеры параллельных программ mpi

Для приема сообщения процесс -получатель должен выполнить функцию:

int MPI_Recv(void *buf, int count, MPI_Datatype type, int source, int tag, MPI_Comm comm, MPI_Status *status),

  • buf, count, type — буфер памяти для приема сообщения, назначение каждого отдельного параметра соответствует описанию в MPI_Send ;
  • source — ранг процесса , от которого должен быть выполнен прием сообщения;
  • tag — тег сообщения, которое должно быть принято для процесса ;
  • comm — коммуникатор, в рамках которого выполняется передача данных;
  • status – указатель на структуру данных с информацией о результате выполнения операции приема данных.
  • буфер памяти должен быть достаточным для приема сообщения. При нехватке памяти часть сообщения будет потеряна и в коде завершения функции будет зафиксирована ошибка переполнения; с другой стороны, принимаемое сообщение может быть и короче, чем размер приемного буфера, в таком случае изменятся только участки буфера, затронутые принятым сообщением;
  • типы элементов передаваемого и принимаемого сообщения должны совпадать;
  • при необходимости приема сообщения от любого процесса — отправителя для параметра source может быть указано значение MPI_ANY_SOURCE (в отличие от функции передачи MPI_Send , которая отсылает сообщение строго определенному адресату);
  • при необходимости приема сообщения с любым тегом для параметра tag может быть указано значение MPI_ANY_TAG (опять-таки, при использовании функции MPI_Send должно быть указано конкретное значение тега);
  • в отличие от параметров » процесс -получатель» и «тег», параметр «коммуникатор» не имеет значения, означающего «любой коммуникатор»;
  • параметр status позволяет определить ряд характеристик принятого сообщения:
  • status.MPI_SOURCE — ранг процесса – отправителя принятого сообщения;
  • status.MPI_TAG — тег принятого сообщения.

Приведенные значения MPI_ANY_SOURCE и MPI_ANY_TAG иногда называют джокерами.

Лекция 2. Основные функции библиотеки MPI.

Значение переменной status позволяет определить количество элементов данных в принятом сообщении при помощи функции:

int MPI_Get_count(MPI_Status *status, MPI_Datatype type, int *count),

  • status — статус операции MPI_Recv ;
  • type — тип принятых данных;
  • count — количество элементов данных в сообщении.

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

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

Параллельные процессы MPI

5.2.1.5. Первая параллельная программа с использованием MPI

Рассмотренный набор функций оказывается достаточным для разработки параллельных программ 4 Как было обещано ранее, количество функций MPI , необходимых для начала разработки параллельных программ , оказалось равным шести. . Приводимая ниже программа является стандартным начальным примером для алгоритмического языка C .

Программа 5.1. Первая параллельная программа с использованием MPI

#include #include «mpi.h» int main(int argc, char* argv[]) < int ProcNum, ProcRank, RecvRank; MPI_Status Status; MPI_Init(argv); MPI_Comm_size(MPI_COMM_WORLD, MPI_Comm_rank(MPI_COMM_WORLD, if ( ProcRank == 0 )< // Действия, выполняемые только процессом с рангом 0 printf(«n Hello from process %3d», ProcRank); for (int i = 1; i < ProcNum; i++ ) < MPI_Recv(Status); printf(«n Hello from process %3d», RecvRank); >> else // Сообщение, отправляемое всеми процессами, // кроме процесса с рангом 0 MPI_Send( MPI_Finalize(); return 0; >

Читайте также:
Программа сбис что означает

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

Hello from process 0 Hello from process 2 Hello from process 1 Hello from process 3

Такой «плавающий» вид получаемых результатов существенным образом усложняет разработку, тестирование и отладку параллельных программ , т.к. в этом случае исчезает один из основных принципов программирования – повторяемость выполняемых вычислительных экспериментов. Как правило, если это не приводит к потере эффективности, следует обеспечивать однозначность расчетов и при использовании параллельных вычислений. Для рассматриваемого простого примера можно восстановить постоянство получаемых результатов при помощи задания ранга процесса -отправителя в операции приема сообщения:

MPI_Recv(Status).

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

Следует отметить еще один важный момент: разрабатываемая с применением MPI программа, как в данном частном варианте, так и в самом общем случае, используется для порождения всех процессов параллельной программы а значит, должна определять вычисления, выполняемые всеми этими процессами . Можно сказать, что MPI — программа является некоторой «макропрограммой», различные части которой используются разными процессами . Так, например, в приведенном примере программы выделенные рамкой участки программного кода не выполняются одновременно ни одним из процессов . Первый выделенный участок с функцией приема MPI_Recv исполняется только процессом с рангом 0 , второй участок с функцией передачи MPI_Send задействуется всеми процессами , за исключением нулевого процесса .

Для разделения фрагментов кода между процессами обычно используется подход, примененный в только что рассмотренной программе, – при помощи функции MPI_Comm_rank определяется ранг процесса , а затем в соответствии с рангом выделяются необходимые для процесса участки программного кода. Наличие в одной и той же программе фрагментов кода разных процессов также значительно усложняет понимание и, в целом, разработку MPI -программы. Как результат, можно рекомендовать при увеличении объема разрабатываемых программ выносить программный код разных процессов в отдельные программные модули (функции). Общая схема MPI -программы в этом случае будет иметь вид:

MPI_Comm_rank(MPI_COMM_WORLD, if ( ProcRank == 0 ) DoProcess0(); else if ( ProcRank == 1 ) DoProcess1(); else if ( ProcRank == 2 ) DoProcess2();

Читайте также:
Как изолировать программу от антивируса

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

MPI_Comm_rank(MPI_COMM_WORLD, if ( ProcRank == 0 ) DoManagerProcess(); else DoWorkerProcesses();

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

  • MPI_ERR_BUFFER — неправильный указатель на буфер;
  • MPI_ERR_TRUNCATE — сообщение превышает размер приемного буфера;
  • MPI_ERR_COMM — неправильный коммуникатор;
  • MPI_ERR_RANK — неправильный ранг процесса и др.

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

Источник: intuit.ru

3. Примеры параллельных программ

Рассмотрим в качестве первого примера программу, выводящую на экран сообщение «Hello» от каждого из процессов.

#include «mpi.h»

#define BUF_LEN 256 /* длина буфера сообщений */

#define MSG_TAG 100 /* метка сообщений */

int main(int argc, char *argv[])

int my_rank; /* ранг текущего

int numprocs; /* общее число

int source; /* ранг отправителя */

int dest; /* ранг получателя */

char message[BUF_LEN];/* буфер для сообщения */

MPI_Status status; /* информация о полученном

/* Начать работу с MPI */

/* Получить номер текущего процесса

в группе всех процессов */

/* Получить общее количество

запущенных процессов */

/* Посылаем сообщения процессу 0,

который их выводит на экран */

if (my_rank != 0)

/* Создаем сообщение */

sprintf(message, «Hello from process %d!»,

/* Отправляем его процессу 0 */

MPI_Send(message, strlen(message) + 1,

MPI_CHAR, dest, MSG_TAG,

/* В процессе 0: получаем сообщение от

процессов 1. numprocs-1 и выводим

его на экран */

MPI_Recv(message, BUF_LEN, MPI_CHAR, source,

/* Заканчиваем работу с MPI */

Компиляция этого файла выполняется командой

$ mpicc MPI_simple.c -o MPI_simple

$ mpirun -np 2 MPI_simple .

Здесь символ $ означает приглашение операционной системы к вводу команды (его набирать не нужно!), опция -np задает количество параллельно работающих процессов (в данном случае 2). Попробуйте его изменить, чтобы выяснить, как это отражается на работе программы.

3.2. Вычисление интеграла

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

,

.

Использовав для приближенного определения каждого из слагаемых

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

Читайте также:
Как включить веб камеру в программе obs

Каждый из процессов инициализирует подсистему MPI с помощью вызова MPI_Init, получает свой номер и общее количество процессов посредством MPI_Comm_rank и MPI_Comm_size. Основная работа производится в функции integrate, по окончании которой процесс заканчивает работу с MPI с помощью MPI_Finalize и завершается. Функция integrate вычисляет свою часть интеграла и прибавляет его к ответу total в процессе с номером 0 посредством MPI_Reduce. Процесс с номером 0 перед окончанием своей работы выводит переменную total на экран.

Входные данные (границы отрезка и количество точек разбиения интервала) принимаются от пользователя в процессе с номером 0. Затем эти данные рассылаются всем остальным процессам с помощью MPI_Bcast.

/* Вычисление определенного интеграла */

#include «mpi.h»

/* Интегрируемая функция */

double f(double x)

/* Вычислить интеграл по отрезку [a,b] с числом

точек разбиений n по формуле трапеций */

double integrate(double a, double b, int n)

double res; /* результат */

double h; /* шаг интегрирования */

return res;

int main(int argc, char *argv[])

int my_rank; /* ранг текущего процесса */

int numprocs; /* общее число процессов */

double a; /* левый конец интервала */

double b; /* правый конец интервала */

int n; /* число точек разбиения */

double len; /* длина отрезка интегрирования

для текущего процесса*/

double local_a; /* левый конец интервала для

текущего процесса */

double local_b; /* правый конец интервала для

текущего процесса */

int local_n; /* число точек разбиения для

текущего процесса */

double local_res;/* значение интеграла в текущем

double result; /* результат интегрирования */

double wtime; /* время работы программы */

/* Начать работу с MPI */

/* Получить номер текущего процесса

в группе всех процессов */

/* Получить общее количество запущенных

/* Получить данные */

if (my_rank == 0)

/* Рассылаем данные из процесса 0 остальным */

/* Синхронизация процессов */

/* Запускаем таймер */

/* Вычисляем отрезок интегрирования

для текущего процесса */

local_a = a + my_rank*len;

local_b = local_a + len;

/* Вычислить интеграл на каждом из процессов */

local_res = integrate(local_a, local_b,

/* Сложить все ответы и передать процессу 0 */

MPI_Reduce(result, 1, MPI_DOUBLE,

MPI_SUM, 0, MPI_COMM_WORLD);

/* Синхронизация процессов */

/* Вычисляем время работы */

wtime = MPI_Wtime() — wtime;

/* Напечатать ответ */

if (my_rank == 0)

printf(«Integral from %.2lf to %.2lf=%.8lfn»,

printf(«Working time: %.2lf secondsn»,

/* Заканчиваем работу с MPI */

Имеет смысл поэкспериментировать с количеством работающих параллельно процессов, чтобы выяснить, как меняется время работы программы.

Источник: studfile.net

Презентация, доклад Параллельное программирование на основе MPI. (Раздел 4.1)

Вы можете изучить и скачать доклад-презентацию на тему Параллельное программирование на основе MPI. (Раздел 4.1). Презентация на заданную тему содержит 56 слайдов. Для просмотра воспользуйтесь проигрывателем, если материал оказался полезным для Вас — поделитесь им с друзьями с помощью социальных кнопок и добавьте наш сайт презентаций в закладки!

Презентации » Информатика » Параллельное программирование на основе MPI. (Раздел 4.1)

Раздел 4_1. Параллельное программирование на основе MPI Образовательный комплекс ВведениеСодержание MPI: основные понятия и определения Введение в MPI ИнициализацияВведение… распределять вычислительную нагрузку, организовать информационное взаимодействие (передачу данных) между процессорами.Введение… В рамках MPI для решения задачи разрабатывается одна программа, онаВведение… В MPI существует множество операций передачи данных: Обеспечиваются разные способыВведение… Что означает MPI? MPI - это стандарт, которому должны удовлетворятьВведение… Достоинства MPI MPI позволяет существенно снизить остроту проблемы переносимости параллельныхВведение История разработки MPI 1992 г. Начало работ над стандартом библиотекиMPI: основные понятия и определения… Понятие параллельной программы Под параллельной программойMPI: основные понятия и определения… В основу MPI положены четыре основныеMPI: основные понятия и определения… Операции передачи данных Основу MPI составляютMPI: основные понятия и определения… Понятие коммуникаторов… Коммуникатор в MPI -MPI: основные понятия и определения… Понятие коммуникаторов В ходе вычислений могутMPI: основные понятия и определения… Типы данных При выполнении операций передачиMPI: основные понятия и определения Виртуальные топологии Логическая топология линий связиВведение в разработку параллельных программ с использованием MPI… Основы MPI… ИнициализацияВведение в разработку параллельных программ с использованием MPI… Основы MPI… ИнициализацияВведение в разработку параллельных программ с использованием MPI… Основы MPI… ОпределениеВведение в разработку параллельных программ с использованием MPI… Основы MPI… ОпределениеВведение в разработку параллельных программ с использованием MPI… Основы MPI… ОпределениеВведение в разработку параллельных программ с использованием MPI… Основы MPI… ПередачаВведение в разработку параллельных программ с использованием MPI… Основы MPI… ПередачаВведение в разработку параллельных программ с использованием MPI… Основы MPI… ПередачаВведение в разработку параллельных программ с использованием MPI… Основы MPI… Прием

>»>

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru