fdvmLDr (1158421), страница 5
Текст из файла (страница 5)
Таким образом, вычисления распределяются в соответствии с размещением данных (параллелизм по данным). В случае размноженной переменной оператор присваивания выполняется на всех процессорах, а в случае распределенного массива - только на процессоре (или процессорах), где размещен соответствующий элемент массива.
Определение "своих" и пропуск "чужих" операторов может вызвать значительные накладные расходы при выполнении программы. Поэтому спецификация распределения вычислений разрешается только для циклов, которые удовлетворяют следующим условиям:
-
цикл является тесно-гнездовым циклом с прямоугольным индексным пространством;
-
распределенные измерения массивов индексируются только регулярными выражениями типа a*I + b , где I - индекс цикла;
-
левые части операторов присваивания одного витка цикла размещены на одном процессоре и, следовательно, виток цикла полностью выполняется на этом процессоре;
-
нет зависимости по данным кроме редукционной зависимости и регулярной зависимости по распределенным измерениям;
-
левая часть оператора присваивания является ссылкой на распределенный массив, редукционную переменную, приватную переменную (см. 5.1.3);
-
нет операторов ввода-вывода и dvm-директив в теле цикла.
Цикл, удовлетворяющий этим условиям, будем называть параллельным циклом. Управляющая переменная последовательного цикла, охватывающего параллельный цикл или вложенного в него, может индексировать только локальные (размноженные) измерения распределенных массивов.
5.1.2. Распределение витков цикла. Директива PARALLEL
Параллельный цикл специфицируется следующей директивой:
| parallel-directive | is PARALLEL ( do-variable-list ) ON iteration-align-spec [ , new-clause ] [ , reduction-clause] [ , shadow-renew-clause] [ , remote-access-clause ] [ , across-clause ] |
| iteration-align-spec | is align-target ( iteration-align-subscript-list ) |
| iteration-align-subscript | is int-expr |
| or do-variable-use | |
| or * | |
| do-variable-use | is [ primary-expr * ] do-variable [ add-op primary-expr ] |
Директива PARALLEL размещается перед заголовком цикла и распределяет витки циклов в соответствии с распределением массива или шаблона. Семантика директивы аналогична семантике директивы ALIGN, где индексное пространство выравниваемого массива заменяется индексным пространством цикла. Индексы циклов в списке do-variable-list перечисляются в том порядке, в котором размещены соответствующие операторы DO в тесно-гнездовом цикле.
Синтаксис и семантика отдельных частей директивы описаны в следующих разделах:
new-clause раздел 5.1.3
reduction-clause раздел 5.1.4
shadow-renew-clause раздел 6.2.2
remote-access-clause раздел 6.3.1
across-clause раздел 6.2.3
Пример 5.1. Распределение витков цикла с регулярными вычислениями.
REAL A(N, M), B(N, M+1), C(N, M), D(N, M)
CDVM$ ALIGN ( I, J ) WITH B( I, J+1 ) :: A, C, D
CDVM$ DISTRIBUTE B ( BLOCK , BLOCK )
. . .
CDVM$ PARALLEL ( I, J ) ON B( I, J+1 )
DO 10 I = 1, N
DO 10 J = 1, M-1
A(I,J) = D(I,J) + C(I,J)
B(I,J+1) = D(I,J) - C(I,J)
10 CONTINUE
Цикл удовлетворяет всем условиям параллельного цикла. В частности, левые части операторов присваивания одного витка цикла A(I,J) и B(I,J+1) размещаются на одном процессоре через выравнивание массивов А и В.
Если левые части операторов присваивания размещены на разных процессорах (распределенный виток цикла), то цикл необходимо разделить на несколько циклов.
Пример 5.2. Разделение цикла
| CDVM$ PARALLEL ( I ) ON A( 2*I ) | |
| DO 10 I = 1, N | DO 10 I = 1, N |
| DO 10 J = 1, M-1 | 10 A(2*I) = . . . |
| A(2*I) = . . . | CDVM$ PARALLEL ( I) ON B( 3*I ) |
| B(3*I) = . . . | DO 11 I = 1, N |
| 10 CONTINUE | 11 B(3*I) = . . . |
Цикл разделен на 2 цикла, каждый из которых удовлетворяет условию параллельного цикла.
5.1.3. Приватные переменные. Спецификация NEW
Если использование переменной локализовано в пределах одного витка цикла, то ее необходимо указать в спецификации NEW:
| new-clause | is NEW ( new-variable-list ) |
| new-variable | is array-name |
| or scalar-variable-name |
NEW-переменные (приватные переменные) не могут быть распределенными массивами. Значение приватной переменной не определено в начале витка цикла и не используется после витка цикла, поэтому в каждом витке цикла может использоваться свой экземпляр приватной переменной.
Пример 5.3. Спецификация приватной переменной.
CDVM$ PARALLEL ( I, J ) ON A( I, J ) , NEW ( X )
DO 10 I = 1, N
DO 10 J = 1, N
X = B(I,J) + C(I,J)
A(I,J) = X
10 CONTINUE
5.1.4. Редукционные операции и переменные. Спецификация REDUCTION
Очень часто в программе встречаются циклы, в которых выполняются редукционные операции - в некоторой переменной суммируются элементы массива или вычисляется максимальное (минимальное) значение. Витки таких циклов можно распределять, если указать спецификацию REDUCTION.
| reduction-clause | is REDUCTION ( [ reduction-group-name : ] reduction-op-list ) |
| reduction-op | is reduction-op-name ( reduction-variable ) |
| or reduction-loc-name ( reduction-variable , location-variable, int-expr) |
| reduction-variable | is array-name |
| or scalar-variable-name |
| location-variable | is array-name |
| reduction-op-name | is SUM |
| or PRODUCT | |
| or MAX | |
| or MIN | |
| or AND | |
| or OR | |
| or EQV | |
| or NEQV |
| reduction-loc-name | is MAXLOC |
| or MINLOC |
Редукционными переменными не могут быть распределенные массивы. Редукционные переменные вычисляются и используются только в операторах определенного вида - редукционных операторах.
Введем следующие обозначения
| rv | - редукционная переменная |
| L | - одномерный массив целого типа |
| n | - число координат минимума или максимума |
| er | - выражение, не содержащее rv |
| Ik | - целая переменная |
| op | - одна из следующих операций языка Фортран: +, -, .OR., .AND., .EQV., .NEQV. |
| ol | - одна из следующих операций языка Фортран: .GE., .GT., .LE., .LT. |
| f | - функция max или min |
В теле цикла редукционный оператор имеет один из следующих видов:
1) rv = rv op er
rv = er op rv
2) rv = f( rv, er )
rv = f( er, rv )
3) if( rv ol er ) rv = er
if( er ol rv ) rv = er
4) if( rv ol er ) then
rv = er
L( 1 ) = e1
. .
L( n ) = en
endif
if( er ol rv ) then
rv = er
L( 1 ) = e1
. . .
L( n ) = en
endif
Соответствие вида оператора, операции языка Фортран и имени редукции FDVM приведено в следующей таблице.
| Вид оператора | операция Фортран | имя редукции FDVM |
| 1 | + | SUM(rv) |
| 1 | * | PRODUCT(rv) |
| 1 | .AND. | AND(rv) |
| 1 | .OR. | OR(rv) |
| 1 | .EQV. | EQV(rv) |
| 1 | .NEQV. | NEQV(rv) |
| 2,3 | MAX(rv) | |
| MIN(rv) | ||
| 4 | MINLOC(rv, L, n) | |
| MAXLOC(rv, L, n) |
Операция MAXLOC (MINLOC) предполагает вычисление максимального (минимального) значения и определение его координат.
Пример 5.4. Спецификация редукции.
S = 0
X = A(1)
Y = A(1)
IMIN(1) = 1
CDVM$ PARALLEL ( I ) ON A( I ) ,
CDVM$ REDUCTION(SUM(S), MAX(X), MINLOC(Y,IMIN,1))
DO 10 I = 1, N
S = S + A(I)
X = MAX(X, A(I))
IF(A(I) .LT. Y) THEN
Y = A(I)
IMIN(1) = I
ENDIF
10 CONTINUE
5.2. Вычисления вне параллельного цикла
Вычисления вне параллельного цикла выполняются по правилу собственных вычислений. Пусть оператор
IF p THEN lh = rh
где p – логическое выражение,
lh – левая часть оператора присваивания (ссылка на скаляр или элемент массива),
rh – правая часть оператора присваивания (выражение),
находится вне параллельного цикла.
Тогда этот оператор будет выполняться на процессоре, где распределены данные со ссылкой lh (процессор own( lh )). Все данные в выражениях p и rh должны быть размещены на процессоре own( lh ). Если какие-либо данные из выражений p и rh отсутствуют на процессоре own( lh ), то их необходимо указать в директиве удаленного доступа (см. 6.1.2) перед этим оператором.














