- •(Вопросы 34-40) содержание
- •5.2. Введение в разработку параллельных программ с использованием mpi
- •5.3. Операции передачи данных между двумя процессами
- •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-программ
- •5.2.1.2. Определение количества и ранга процессов
- •5.2.1.3. Передача сообщений
- •5.2.1.4. Прием сообщений
- •5.2.1.5. Первая параллельная программа с использованием mpi
- •5.2.2. Определение времени выполнение mpi-программы
- •5.2.3. Начальное знакомство с коллективными операциями передачи данных
- •5.2.3.1. Передача данных от одного процесса всем процессам программы
- •5.2.3.2. Передача данных от всех процессов одному процессу. Операция редукции
- •5.2.3.3. Синхронизация вычислений
- •5.2.3.4. Аварийное завершение параллельной программы
- •5.3. Операции передачи данных между двумя процессами
- •5.3.1. Режимы передачи данных
- •5.3.2. Организация неблокирующих обменов данными между процессами
- •5.3.3. Одновременное выполнение передачи и приема
- •5.4. Коллективные операции передачи данных
- •5.4.1. Обобщенная передача данных от одного процесса всем процессам
- •5.4.2. Обобщенная передача данных от всех процессов одному процессу
- •5.4.3. Общая передача данных от всех процессов всем процессам
- •5.4.4. Дополнительные операции редукции данных
- •5.4.5. Сводный перечень коллективных операций данных
- •5.5. Производные типы данных в mpi
- •5.5.1. Понятие производного типа данных
- •5.5.2. Способы конструирования производных типов данных
- •5.5.2.1. Непрерывный способ конструирования
- •5.5.2.2. Векторный способ конструирования
- •5.5.2.3. Индексный способ конструирования
- •5.5.2.4. Структурный способ конструирования
- •5.5.3. Объявление производных типов и их удаление
- •5.5.4. Формирование сообщений при помощи упаковки и распаковки данных
- •5.6. Управление группами процессов и коммуникаторами
- •5.6.1. Управление группами
- •5.6.2. Управление коммуникаторами
- •5.7. Виртуальные топологии
- •5.7.1. Декартовы топологии (решетки)
- •5.7.2. Топологии графа
- •5.8. Дополнительные сведения о mpi
- •5.8.1. Разработка параллельных программ с использованием mpi на алгоритмическом языке Fortran
- •5.8.2. Общая характеристика среды выполнения mpi-программ
- •5.8.3. Дополнительные возможности стандарта mpi-2
- •5.9. Краткий обзор лекции
- •6. Параллельные методы умножения матрицы на вектор
- •6.1. Принципы распараллеливания
- •6.2. Постановка задачи
- •6.3. Последовательный алгоритм
- •6.4. Разделение данных
- •6.5. Умножение матрицы на вектор при разделении данных по строкам
- •6.5.1. Выделение информационных зависимостей
- •6.5.2. Масштабирование и распределение подзадач по процессорам
- •6.5.3. Анализ эффективности
- •6.5.4. Программная реализация
- •6.5.5. Результаты вычислительных экспериментов
- •6.6. Умножение матрицы на вектор при разделении данных по столбцам
- •6.6.1. Определение подзадач и выделение информационных зависимостей
- •6.6.2. Масштабирование и распределение подзадач по процессорам
- •6.6.3. Анализ эффективности
- •6.6.4. Результаты вычислительных экспериментов
- •6.7. Умножение матрицы на вектор при блочном разделении данных
- •6.7.1. Определение подзадач
- •6.7.2. Выделение информационных зависимостей
- •6.7.3. Масштабирование и распределение подзадач по процессорам
- •6.7.4. Анализ эффективности
- •6.7.5. Результаты вычислительных экспериментов
- •6.8. Краткий обзор лекции
5.2.1.2. Определение количества и ранга процессов
Определение количествапроцессовв выполняемойпараллельной программеосуществляется при помощи функции:
int MPI_Comm_size(MPI_Comm comm, int *size),
где
comm — коммуникатор, размер которого определяется,
size — определяемое количество процессов в коммуникаторе.
Для определения ранга процессаиспользуется функция:
int MPI_Comm_rank(MPI_Comm comm, int *rank),
где
comm — коммуникатор, в котором определяется ранг процесса,
rank — ранг процесса в коммуникаторе.
Как правило, вызов функций MPI_Comm_sizeиMPI_Comm_rankвыполняется сразу послеMPI_Initдля получения общего количествапроцессови ранга текущегопроцесса:
#include "mpi.h"
int main(int argc, char *argv[]) {
int ProcNum, ProcRank;
<программный код без использования функций MPI>
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ProcNum);
MPI_Comm_rank(MPI_COMM_WORLD, &ProcRank);
<программный код с использованием функций MPI>
MPI_Finalize();
<программный код без использования функций MPI>
return 0;
}
Следует отметить:
коммуникатор MPI_COMM_WORLD, как отмечалось ранее, создается по умолчанию и представляет все процессы выполняемой параллельной программы;
ранг, получаемый при помощи функции MPI_Comm_rank, является рангом процесса, выполнившего вызов этой функции, т. е. переменная ProcRank примет различные значения у разных процессов.
5.2.1.3. Передача сообщений
Для передачи сообщенияпроцесс- отправитель должен выполнить функцию:
int MPI_Send(void *buf, int count, MPI_Datatype type, int dest,
int tag, MPI_Comm comm),
где
buf — адрес буфера памяти, в котором располагаются данные отправляемого сообщения;
count — количество элементов данных в сообщении;
type — тип элементов данных пересылаемого сообщения;
dest — ранг процесса, которому отправляется сообщение;
tag — значение-тег, используемое для идентификации сообщения;
comm — коммуникатор, в рамках которого выполняется передача данных.
Для указания типа пересылаемых данных в MPIимеется ряд базовых типов, полный список которых приведен втабл. 5.1.
Таблица 5.1. Базовые (пpедопpеделенные) типы данных MPI для алгоритмического языка C | |
Тип данных MPI |
Тип данных C |
MPI_BYTE |
|
MPI_CHAR |
signed char |
MPI_DOUBLE |
double |
MPI_FLOAT |
float |
MPI_INT |
int |
MPI_LONG |
long |
MPI_LONG_DOUBLE |
long double |
MPI_PACKED |
|
MPI_SHORT |
short |
MPI_UNSIGNED_CHAR |
unsigned char |
MPI_UNSIGNED |
unsigned int |
MPI_UNSIGNED_LONG |
unsigned long |
MPI_UNSIGNED_SHORT |
unsigned short |
Следует отметить:
отправляемое сообщение определяется через указание блока памяти (буфера), в котором это сообщение располагается. Используемая для указания буфера триада (buf, count, type) входит в состав параметров практически всех функций передачи данных;
процессы, между которыми выполняется передача данных, в обязательном порядке должны принадлежать коммуникатору, указываемому в функции MPI_Send;
параметр tag используется только при необходимости различения передаваемых сообщений, в противном случае в качестве значения параметра может быть использовано произвольное положительное целое число2) (см. также описание функции MPI_Recv).
Сразу же после завершения функции MPI_Sendпроцесс-отправитель может начать повторно использовать буфер памяти, в котором располагалось отправляемое сообщение. Также следует понимать, что в момент завершения функцииMPI_Sendсостояние самого пересылаемого сообщения может быть совершенно различным: сообщение может располагаться впроцессе-отправителе, может находиться в состоянии передачи, может храниться впроцессе-получателе или же может быть принятопроцессом-получателем при помощи функцииMPI_Recv. Тем самым, завершение функцииMPI_Sendозначает лишь, что операция передачи начала выполняться и пересылка сообщения рано или поздно будет выполнена.
Пример использования функции будет представлен после описания функции MPI_Recv