fdvmLDr (1158337), страница 3
Текст из файла (страница 3)
Пример 4.1. Распределение по формату BLOCK
| A | B | C | ||||
| R(1) | 1 | 1 | 1 | |||
| 2 | 2 | 2 | ||||
| CDVM$ PROCESSORS R( 4 ) | 3 | 3 | 3 | |||
| 4 | ||||||
| REAL A (12), B(13), C(11) | R(2) | 4 | 5 | 4 | ||
| 5 | 6 | 5 | ||||
| 6 | 7 | 6 | ||||
| CDVM$ DISTRIBUTE A (BLOCK) ONTO R | 8 | |||||
| R(3) | 7 | 9 | 7 | |||
| CDVM$ DISTRIBUTE (BLOCK) ONTO R :: B | 8 | 10 | 8 | |||
| 9 | 11 | 9 | ||||
| 12 | ||||||
| CDVM$ DISTRIBUTE C (BLOCK) | ||||||
| R(4) | 10 | 13 | 10 | |||
| 11 | 11 | |||||
| 12 | ||||||
4.1.2. Формат GEN_BLOCK
Распределение блоками разных размеров позволяет влиять на балансировку загрузки процессоров для алгоритмов, которые выполняют разное количество вычислений на различных участках области данных.
Пусть NB( 1:P ) - массив целых чисел. Следующая директива
CDVM$ DISTRIBUTE A( GEN_BLOCK(NB)) ONTO R
разделяет массив A на P блоков. Блок i размера NB( i ) распределяется на процессор R( i ). При этом
| P | |
| NB( i ) = N | |
| i=1 |
Пример 4.2. Распределение неравными блоками.
| A | ||
| R(1) | 1 | |
| CDVM$ PROCESSORS R( 4 ) | 2 | |
| R(2) | 3 | |
| INTEGER BS(4) | 4 | |
| 5 | ||
| 6 | ||
| REAL A(12) | ||
| R(3) | 7 | |
| 8 | ||
| CDVM$ DISTRIBUTE A ( GEN_BLOCK( BS ) ) ONTO R | 9 | |
| 10 | ||
| DATA BS / 2, 4, 4, 2 / | R(4) | 11 |
| 12 | ||
4.1.3. Формат WGT_BLOCK
Формат WGT_BLOCK определяет распределение блоками по их относительным “весам”.
Пусть задан формат WGT_BLOCK(WB, NBL).
Для 1 i NBL, WB(i) определяет вес i‑ого блока. Блоки распределяются на P процессоров с балансировкой сумм весов блоков на каждом процессоре. При этом должно выполняться условие
P NBL
Определим вес процессора как сумму весов всех блоков, распределенных на него. Измерение массива распределяется пропорционально весам процессоров.
Формат BLOCK является частным случаем формата WGT_BLOCK(WB,P), где WB(i) = 1 для 1 i P и NBL = P.
Формат GEN_BLOCK с некоторой точностью является частным случаем формата WGT_BLOCK.
Пример 4.2 можно переписать с использованием формата WGT_BLOCK следующим образом.
Пример 4.3. Распределение блоками по весам.
CDVM$ PROCESSORS R( 4 )
DOUBLE PRECISION WB(12)
REAL A(12)
CDVM$ DISTRIBUTE A ( WGT_BLOCK( WB, 12 ) ) ONTO R
DATA WB / 2., 2.,1., 1., 1., 1., 1., 1., 1., 1., 2., 2. /
В примере 4.3 P = 4 и распределение идентично примеру 4.2.
В отличие от распределения неравными блоками, распределение по формату WGT_BLOCK можно выполнить для любого числа процессоров в диапазоне 1 P NBL. Для данного примера размер массива процессоров R может изменяться от 1 до 12.
4.1.4. Формат *
Формат * означает, что измерение будет полностью локализовано на каждом процессоре (нераспределенное или локальное измерение).
4.1.5. Многомерные распределения
При многомерных распределениях формат распределения указывается для каждого измерения. Между измерениями распределяемого массива и массива процессоров устанавливается следующее соответствие.
Пусть массив процессоров имеет n измерений. Пронумеруем измерения массива без формата * слева направо d1, ..., dk.. Тогда измерение di будет распределяться на i-ое измерение массива процессоров. При этом должно выполняться условие kn.
Пример 4.4. Одномерное распределение.
| CDVM$ PROCESSORS R1( 2 ) | Блоки A | Процессоры | |||||
| REAL A(100,100) | |||||||
| CDVM$ DISTRIBUTE A (BLOCK, *) ONTO R1 | 1 | A( 1: 50,1:100) | 1 | 1 | |||
| 2 | A(51:100,1:100) | 2 | 2 | ||||
Пример 4.5. Двумерное распределение.
| CDVM$ PROCESSORS R2( 2, 2 ) | Блоки A | Процессоры | |||
| REAL A(100,100) | 1 | 2 | |||
| CDVM$ DISTRIBUTE A (BLOCK,BLOCK) | 1 | 2 | 1 | 1 | 2 |
| CDVM$* ONTO R2 | 3 | 4 | 2 | 3 | 4 |
4.2. Распределение динамических массивов
4.2.1. Динамические массивы в программе на языке Фортран 77
Отсутствие средств работы с динамическими массивами в языке Фортран 77 заставляет пользователей моделировать динамическую память с помощью так называемых рабочих массивов. Динамическая память описывается как одномерный массив большого размера. Динамические массивы разной формы определяются как непрерывные сегменты в этом рабочем массиве.
Пример 4.6. Использование рабочего массива.
REAL HEAP(100000)
READ (6 , *) N, M
C в программе требуются динамические массивы размера N N и M M
CALL SUB1(HEAP(1), N, HEAP(1+N*N), M)
END
SUBROUTINE SUB1(A, N, B, M)
DIMENSION A(N , N), B(M , M)
. . .
END
Анализ существующих программ показал отсутствие определенной дисциплины работы с моделируемыми динамическими массивами. В частности, отсутствует явная фиксация размещения массива в памяти. Обращение к динамическому массиву осуществляется ссылкой на рабочий массив. Это делает невозможным для компилятора определить форму массива.
4.2.2. Динамические массивы в модели FDVM. Директива POINTER
Предлагаемая модель является подмножеством модели динамических массивов Фортран 90 и позволяет без изменений выполнять эту модель в трех средах программирования
-
последовательная программа на языке Фортран 77,
-
параллельная программа на языке FDVM,
-
параллельная программа на языке HPF.
Для динамических массивов, распределяемых по умолчанию, FDVM разрешает использовать любые способы моделирования динамической памяти. Для динамических массивов, распределяемых директивами DISTRIBUTE и ALIGN, FDVM определяет следующую дисциплину размещения и использования динамических массивов.
-
Все явно распределяемые динамические массивы размещаются в пуле динамической памяти с именем HEAP
REAL HEAP (MAXM)
где MAXM - количество слов динамической памяти.
-
Тип данных и количество измерений динамического массива фиксируется следующей директивой FDVM
| pointer-directive | is type , POINTER ( dimension-list ) :: pointer-name-list |
| dimension | is : |
| pointer-name | is scalar-int-variable-name |
| or int-array-name |
type определяет тип данных динамического массива. Переменные, специфицированные директивой POINTER, имеют следующие ограничения.
-
Переменной с атрибутом POINTER может быть присвоено только значение функции ALLOCATE или значение другой переменной с атрибутом POINTER.
-
Переменные с атрибутом POINTER в левой и правой части оператора присваивания должны иметь одинаковое количество измерений.
-
Размеры каждого измерения и размещение динамического массива в HEAP фиксируется следующим оператором
pointer = ALLOCATE ( sdim ,... )
где
| pointer - | ссылка на целочисленную переменную (скаляр или элемент массива) с атрибутом POINTER |
| sdim - | целочисленный одномерный массив размера ndim. ndim - количество измерений многомерного массива, размещаемого в динамической памяти HEAP. Значение sdim( i ) определяет размер i-ого измерения. Размер выделяемого сегмента равен sdim( 1 ) sdim( 2 ).... sdim( ndim ). |
Целочисленная функция ALLOCATE выдает номер начального элемента выделяемого сегмента динамической памяти HEAP. Функция ALLOCATE программируется пользователем, поэтому она может иметь дополнительные параметры помимо обязательного параметра sdim.
-
В процедуре, где производится размещение динамического массива, разрешается только следующий тип ссылки на динамический массив
HEAP( pointer )
При этом такая ссылка может быть только фактическим аргументом вызова функции или подпрограммы.
Пусть в программе используется несколько пулов динамической памяти с идентификаторами ID1 , …, IDn. Нет необходимости переписывать программу с одним пулом динамической памяти HEAP. Достаточно указать следующую спецификацию















