- •(Вопросы 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.5.2. Способы конструирования производных типов данных
Для снижения сложности в MPIпредусмотрено несколько различных способов конструирования производных типов:
непрерывный способ позволяет определить непрерывный набор элементов существующего типа как новый производный тип;
векторный способ обеспечивает создание нового производного типа как набора элементов существующего типа, между элементами которого имеются регулярные промежутки по памяти. При этом размер промежутков задается в числе элементов исходного типа, в то время как в варианте H-векторного способа этот размер указывается в байтах;
индексный способ отличается от векторного метода тем, что промежутки между элементами исходного типа могут иметь нерегулярный характер (имеется и H-индексный способ, отличающийся способом задания промежутков);
структурный способ обеспечивает самое общее описание производного типа через явное указание карты создаваемого типа данных.
Далее перечисленные способы конструирования производных типов данных будут рассмотрены более подробно.
5.5.2.1. Непрерывный способ конструирования
При непрерывном способеконструирования производного типа данных вMPIиспользуется функция:
int MPI_Type_contiguous(int count, MPI_Data_type oldtype,
MPI_Datatype *newtype),
где
count — количество элементов исходного типа;
oldtype — исходный тип данных;
newtype — новый определяемый тип данных.
Как следует из описания, новый тип newtypeсоздается какcountэлементов исходного типаoldtype. Например, если исходный тип данных имеет карту типа
{(MPI_INT, 0), (MPI_DOUBLE, 8)},
то вызов функции MPI_Type_contiguousс параметрами
MPI_Type_contiguous(2, oldtype, &newtype);
приведет к созданию типа данных с картой типа
{(MPI_INT, 0), (MPI_DOUBLE, 8), (MPI_INT, 16), (MPI_DOUBLE, 24)}.
В определенном плане наличие непрерывного способа конструирования является избыточным, поскольку использование аргумента countв процедурахMPIравносильно использованию непрерывного типа данных такого же размера.
5.5.2.2. Векторный способ конструирования
При векторном способеконструирования производного типа данных вMPIприменяются функции
int MPI_Type_vector(int count, int blocklen, int stride,
MPI_Data_type oldtype, MPI_Datatype *newtype) и
int MPI_Type_hvector(int count, int blocklen, MPI_Aint stride,
MPI_Data_type oldtype, MPI_Datatype *newtype),
где
count — количество блоков;
blocklen — размер каждого блока;
stride — количество элементов, расположенных между двумя соседними блоками;
oldtype — исходный тип данных;
newtype — новый определяемый тип данных.
Отличие способа конструирования, определяемого функцией MPI_Type_hvector, состоит лишь в том, что параметрstrideдля определения интервала между блоками задается в байтах, а не в элементах исходного типа данных.
Как следует из описания, при векторном способе новый производный тип создается как набор блоков из элементов исходного типа, при этом между блоками могут иметься регулярные промежутки по памяти. Приведем несколько примеров использования данного способа конструирования типов:
конструирование типа для выделения половины (только четных или только нечетных) строк матрицы размером n×n:
MPI_Type_vector(n / 2, n, 2 * n, &StripRowType, &ElemType),
конструирование типа для выделения столбца матрицы размером n×n:
MPI_Type_vector(n, 1, n, &ColumnType, &ElemType),
конструирование типа для выделения главной диагонали матрицы размером n×n:
MPI_Type_vector(n, 1, n + 1, &DiagonalType, &ElemType).
С учетом характера приводимых примеров можно упомянуть имеющуюся в MPIвозможность создания производных типов для описания подмассивов многомерных массивов при помощи функции (данная функция предусматривается стандартомMPI-2):
int MPI_Type_create_subarray(int ndims, int *sizes, int *subsizes,
int *starts, int order, MPI_Data_type oldtype, MPI_Datatype *newtype),
где
ndims — размерность массива;
sizes — количество элементов в каждой размерности исходного массива;
subsizes — количество элементов в каждой размерности определяемого подмассива;
starts — индексы начальных элементов в каждой размерности определяемого подмассива;
order — параметр для указания необходимости переупорядочения;
oldtype — тип данных элементов исходного массива;
newtype — новый тип данных для описания подмассива.