FOR( i, N )

реклама
Методика распараллеливания
программ в модели DVM
Институт прикладной математики
им. М.В.Келдыша РАН
http://www.keldysh.ru/pages/dvm
Модель DVM
 Высокоуровневая модель параллелизма без явной
ориентации на общую или распределенную память
 Ориентация на пользователей в области.
вычислительной математики. Основные понятия:
дискретные пространства в декартовых координатах,
отображения и пересечения пространств.
 Язык распараллеливания в модели DVM - язык
спецификаций масштабируемых параллельных
программ.
Средства программирования
C-DVM
= Язык Си + специальные макросы
Fortran-DVM = Язык Фортран + специальные
комментарии
 Специальные комментарии и макросы являются
высокоуровневыми спецификациями параллелизма в
терминах последовательной программы
 Отсутствуют низкоуровневые передачи данных и
синхронизации
 Последовательный стиль программирования
 Спецификации параллелизма «невидимы» для
стандартных компиляторов
 Существует только один экземпляр программы для
последовательного и параллельного счета
Состав DVM-системы
 Компилятор C-DVM
 Компилятор Fortran-DVM
 Система поддержки параллельного
выполнения (Lib-DVM)
 DVM-отладчик
 Анализатор производительности
DVM-программ
 Предсказатель производительности
DVM-программ
Правило собственных вычислений:
OWN(A[i]) - процессор, на который распределен A[i]
A[i] = expr
Оператор всегда выполняется на процессоре
OWN(A[i])
Локализация данных:
Операнды expr распределены на процессор
OWN(A[i])
Распараллеливание
последовательной программы
• Согласованное распределение массивов данных и
параллельных циклов на массив виртуальных
процессоров.
Цель: максимум параллелизма и максимум
локализации
• Определение общих (не локальных данных) и их
спецификация.
Общие данные: данные, вычисляемые на одних
процессорах и используемые на других
процессорах.
Выполнение программы
Модель: одна программа - множество потоков
данных
На всех процессорах - одна и та же программа
Проба: свой - “чужой” оператор по правилу
собственных вычислений
Абстрактная схема распределения
данных и витков параллельных циклов
Объекты:
P - индексное пространство массива виртуальных
процессоров, определяется пользователем и
задается при запуске программы
Ai -
индексное пространство i-ого массива данных
Lj -
индексное пространство j-ого параллельного
цикла
Директивы распределения устанавливают
соответствие между точками (элементами)
индексных пространств:
ALIGN:
Ai1=>Ai2 Каждой точке (элементу) Ai2
ставится в соответствие подмножество
точек (элементов) массива Ai1
PARALLEL: Lj=>Ai Каждой точке (элементу) Ai
ставится в соответствие подмножество
точек (витков цикла) Lj
DISTRIBUTE: Ai=>P Каждой точке (виртуальному
процессору) P ставится в соответствие
подмножество точек (элементов)
массива Ai
Отображение последовательной программы
Массивы
ALIGN
Массивы
DISTRIBUTE
PARALLEL
Циклы
PARALLEL
DISTRIBUTE
Массив
виртуальных
процессоров
Физические
процессоры
Массив
задач
MAP
Распределение данных
DISTRIBUTE
DVM( DISTRIBUTE f1…fk )<описание-массива-на-языке-Си>
где fi = [ BLOCK ] - распределение равными блоками
[]
(распределенное измерение)
- распределение целым измерением
(локальное измерение)
k
- количество измерений массива
P(m)
- линейка виртуальных процессоров
Распределение данных
DISTRIBUTE
Примеры:
DVM( DISTRIBUTE [ BLOCK ] ) float A[N];
DVM( DISTRIBUTE [ ] )
float A[N];
DVM( DISTRIBUTE [ BLOCK ] [ ] ) float B[N][N];
DVM( DISTRIBUTE [ ] [ BLOCK ] ) float B[N][N];
P(m1,m2) - массив виртуальных процессоров
Локализация данных
ALIGN
DVM( ALIGN a1…an WITH B b1…bm )
<описание-массива-A-на-языке-Си>
где ai - параметр i-го измерения выравниваемого массива А
bj - параметр j-го измерения базового массива B
n - количество измерений массива А
m - количество измерений массива В
ai = a[Idi]
[ ]
bj=[c*Idj +d]
[ ]
Idi, Idj - идентификаторы
c, d - целочисленные константы
Локализация данных
ALIGN
Примеры:
DVM( ALIGN [ i ] WITH B[ 2*i+1] )
float A[N];
DVM( ALIGN [ i ] [ j ] WITH C[ j ] [ i ] ) float D[N][N];
DVM( ALIGN [ i ] WITH C[ ] [ i ] )
float E[N];
DVM( ALIGN [ i ] [ ] WITH B[ i ] )
float C[N][N];
Распределение витков цикла
PARALLEL
Макросы заголовков циклов:
# define DO ( v, f, u, s ) for(v=f; v<=u; v+=s)
# define FOR ( v, h )
for(v=0; v<=h-1; v+=1)
Параллельный цикл - массив витков цикла
• тесно-гнездовой цикл
• прямоугольное индексное пространство
• виток цикла - неделимый объект
(выполняется на одном процессоре)
Распределение витков цикла
PARALLEL
DVM( PARALLEL [ I1 ]… [ In ] ON A e1… em )
где
Ij
n
- индекс j-го заголовка параллельного цикла,
- количество заголовков цикла,
m - количество измерений массива,
A - идентификатор распределенного массива,
ei = [a*Ik+b], a, b - целочисленные переменные
Распределение витков цикла
PARALLEL
Цикл не удовлетворяет требованиям массива витков цикла:
Не тесно-гнездовой цикл
FOR(i,N)
{ a=5.;
FOR(j,N)
{ . . . }
}
Не прямоугольное индексное пространство
FOR(i,N)
DO(j,i,N,1)
{ . . . }
Распределение витков цикла
PARALLEL
Цикл не удовлетворяет требованиям массива витков цикла:
Виток цикла на разных процессорах
FOR(i,N)
FOR(i,N)
{ D[2*i] = ...;
{ D[2*i] = ...; }
D[2*i+1]= …; }
FOR(i,N)
{D[2*i+1]= …; }
DVM( DISTRIBUTE [ BLOCK ] [ BLOCK ] ) float A[N+1][N+1],
B[N][N];
FOR(i,N)
FOR(j,N)
{ A[i+1][j+1] = …;
B[i][j] = …; }
DVM( ALIGN [ i ] [ j ] WITH A[i+1] [j+1] ) float B[N][N];
Общие (удаленные) данные
• Сравнение индексных выражений по
•
распределенным измерениям левой и
правой части оператора присваивания
Выражение условного оператора - правая
часть
A[i] = (C[i] > D[i]) ? B[i] : 0.
Локализация данных
DVM( DISTRIBUTE [ BLOCK ] ) float A[N];
DVM( ALIGN [ i ] WITH A[ i ] ) float B[N],C[N];
DVM( PARALLEL [ i ] ON A[ i ] )
FOR( i, N )
{ A[i] = B[i] + C[i] ; }
Локализация с помощью
TEMPLATE
DVM( DISTRIBUTE [ BLOCK ] ; TEMPLATE [N+d1+d2] )
void *TABC;
DVM( ALIGN [ i ] WITH TABC[ i ] )
DVM( ALIGN [ i ] WITH TABC[ i +d1] )
DVM( ALIGN [ i ] WITH TABC[ i +d1+d2] )
DVM( PARALLEL [ i ] ON A[ i ] )
FOR( i, N )
{ A[i] = B[i-d1] + C[i+d2] ; }
float B[N];
float A[N];
float C[N];
Схема отображения
ALIGN
P1
TABC
B
d1
A
d1+d2
C
P2
P3
P4
Общие данные типа SHADOW
DVM( DISTRIBUTE [ BLOCK ] )
float A[N];
DVM( ALIGN [ i ] WITH A[ i ]; SHADOW [d1:d2]) float B[N];
DVM( PARALLEL [ i ] ON A[ i ] ; SHADOW_RENEW B)
DO( i,d1, N-d2-1,1 )
{ A[i] = B[i-d1] + B[i+d2] ; }
Общие данные типа ACROSS
DVM( DISTRIBUTE [ BLOCK ]; SHADOW [d1:d2]) float A[N];
DVM( PARALLEL [ i ] ON A[ i ] ; ACROSS A[d1:d2])
DO( i,d1, N-d2-1,1 )
{ A[i] = A[i-d1] + A[i+d2] ; }
Общие данные типа
REMOTE_ACCESS
DVM( DISTRIBUTE [ BLOCK ] ) float A[N] , C[2*N];
DVM( PARALLEL [ i ] ON A[ i ]
; REMOTE_ACCESS C[5] C[i+N] )
FOR( i, N )
{ A[i] = C[5] + C[i+N] ; }
Общие данные типа REDUCTION
DVM( DISTRIBUTE [ BLOCK ] )
float A[N];
DVM( PARALLEL [ i ] ON A[ i ] ; REDUCTION SUM (s) )
FOR( i, N )
{ s = s + A[i] ; }
DVM( DISTRIBUTE [ BLOCK ] ; TEMPLATE [N] ) void *TM;
DVM( PARALLEL [ i ] ON TM[ i ]
; REDUCTION PRODUCT (sm) )
FOR( i, N )
{ sm = sm * i ; }
Параллельный цикл
• Левая часть: распределенный массив,
•
редукционная переменная, приватная
переменная.
Распределенный цикл => распределенное
измерение
• Локальный цикл => локальное измерение
Программа JACOBI на C-DVM
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#define Max(a,b) ((a)>(b)?(a):(b))
/* dummy macros for standard C compiler */
#define DVM(dvmdir)
/* macros for DVM-loops */
#define DO(v,l,h,s)
#define L 8
#define ITMAX 20
int i,j,it,k;
double eps;
double MAXEPS
FILE *f;
for(v=(l); v<=(h); v+=(s))
= 0.5;
/* 2D arrays block distributed along 2 dimensions */
DVM(DISTRIBUTE [BLOCK][BLOCK]) double A[L][L];
DVM(ALIGN [i][j] WITH A[i][j]) double B[L][L];
int main(int an, char **as) {
/* 2D loop with base array A */
DVM(PARALLEL [i][j] ON A[i][j])
DO(i,0,L-1,1)
DO(j,0,L-1,1)
{A[i][j]=0.;
B[i][j]=1.+i+j;}
Программа JACOBI на C-DVM
/****** iteration loop *************************/
DO(it,1,ITMAX,1)
{ eps= 0.;
/* Parallel loop with base array A
/* calculating maximum in variable eps
*/
*/
DVM(PARALLEL [i][j] ON A[i][j] ; REDUCTION MAX(eps) )
DO(i,1,L-2,1)
DO(j,1,L-2,1)
{eps = Max(fabs(B[i][j]-A[i][j]),eps);
A[i][j] = B[i][j]; }
/* Parallel loop with base array B and
*/
/* with prior updating shadow elements of array A */
DVM(PARALLEL [i][j] ON B[i][j]; SHADOW_RENEW A)
DO(i,1,L-2,1)
DO(j,1,L-2,1)
B[i][j] = (A[i-1][j]+A[i+1][j]+
A[i][j-1]+A[i][j+1])/4.;
printf( "it=%4i eps=%f\n", it,eps);
if (eps < MAXEPS) break;
}/*DO it*/
f=fopen("jacobi.dat","wb");
fwrite(B,sizeof(double),L*L,f);
return 0;
}
Distribution of array A [8][8]
processor
arrangement
1
3*3
2
3
A11
A12
A13
A14
A13
A14
A15
A16
A17
A16
A 17
A18
A21
A22
A23
A24
A23
A24
A25
A26
A27
A26
A 27
A28
A31
A32
A33
A34
A33
A34
A35
A36
A37
A36
A 37
A38
A41
A42
A43
A44
A45
A46
A47
A48
A31
A32
A33
A34
A35
A36
A37
A38
A41
A42
A43
A44
A43
A44
A45
A46
A47
A46
A47
A48
A51
A52
A53
A54
A53
A54
A55
A56
A57
A56
A57
A58
A61
A62
A63
A64
A63
A64
A65
A66
A67
A66
A67
A68
A71
A72
A73
A74
A75
A76
A77
A78
A61
A62
A63
A64
A65
A66
A67
A68
A71
A72
A73
A74
A73
A74
A75
A76
A77
A76
A 77
A78
A81
A82
A83
A84
A83
A84
A85
A86
A87
A86
A 87
A88
1
2
3
shadow
imported
edges
elements
Программа SOR на C-DVM
#include <stdlib.h>
#include <stdio.h>
#define DVM(dvmdir)
#define DO(v,l,h,s) for(v=l; v<=h; v+=s)
#define L 8
#define ITMAX 20
int i,j, it, k;
FILE *f;
DVM(DISTRIBUTE [BLOCK][BLOCK]) double A[L][L];
int main(int an, char **as) {
DO(it,1,ITMAX,1) /****** iteration loop ******/
{ eps= 0.;
DVM(PARALLEL [i][j] ON A[i][j] ; ACROSS A[1:1][1:1];
REDUCTION MAX(eps) )
DO(i,1,L-2,1)
DO(j,1,L-2,1)
{ double b;
b=(A[i-1][j]+A[i+1][j]+A[i][j-1]+A[i][j+1])/4.;
eps = Max(fabs(b-A[i][j]),eps);
A[i][j] = b; }
printf( "it=%4i eps=%3.3E\n", it,eps);
if (eps < MAXEPS) break;
}/*DO it*/
return 0; }
Параллелизм по гиперплоскостям
CDVM$ DISTRIBUTE A (BLOCK,BLOCK)
j
i
t1
t2
t3
Конвейерный параллелизм
CDVM$ DISTRIBUTE A (BLOCK,*)
j
i
p0 t1 t2 t3 t4 t5 t6 t7
p1 t2 t3 t4 t5 t6 t7 t8
p2 t3 t4 t5 t6 t7 t8 t9
Оптимизация
1. Совмещение вычислений и доступа к общим
данным
2. Избыточные вычисления вместо общих данных
SHADOW
3. Асинхронное копирование вместо общих
данных REMOTE
Спецификация обновления значений
общих данных
• Перед циклом использования
• Между циклом вычислений и циклом
•
•
использования
Матрица цикл-массив ({use,def})
Порядок выполнения циклов (граф управления)
Совмещение вычислений и
доступа к общим данным
DVM(CREATE_SHADOW_GROUP grshad: A);
. . .
DVM(SHADOW_START grshad );
. . .
DVM(PARALLEL [ i ] [ j ] ON A[ i ] [ j ];
SHADOW_WAIT grshad )
DO(i,1,L-2,1)
DO(j,1,L-2,1)
B[i][j] = (A[i-1][j]+A[i+1][j]+A[i][j-1]+A[i][j+1])/4;
Избыточные вычисления
DVM(PARALLEL [i] ON A[i]; SHADOW_COMPUTE)
FOR(i,n)
A[i] = i;
DVM(PARALLEL [i] ON A[i] )
DO(i,1,n-2,1)
C[i] = A[i-1] +A[i+1];
Асинхронное копирование
секций массивов
k = N/4 - 1;
FOR (i, N-1)
FOR (j, N-1)
A[ i+k ] [ j+k ] = f( A[ 2*i ] [ 2*j ] ) ;
2N
2N
N
N
DVM( DISTRIBUTE [ BLOCK ] [ BLOCK ] )
float A[2*N][2*N];
DVM( ALIGN [ i ] [ j ] WITH A[ i] [ j ] ) float B[2*N][2*N];
DVM( COPY_FLAG) void *flagS;
k = N/4 - 1;
DVM( PARALLEL [ i ] [ j ] ON B[2*i] [2*j] )
FOR (i, N-1)
FOR (j, N-1)
B[ 2*i ] [ 2*j ] = f( A[ 2*i ] [ 2*j ] ) ;
DVM( COPY_START &flagS)
FOR (i, N-1)
FOR (j, N-1)
A[ i+k ] [ j+k ] = B[ 2*i ] [ 2*j ] ;
DVM( COPY_WAIT &flagS)
Скачать