Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Zrównoleglanie programu sekwencyjnego

Podobne prezentacje


Prezentacja na temat: "Zrównoleglanie programu sekwencyjnego"— Zapis prezentacji:

1 Zrównoleglanie programu sekwencyjnego
1. Analiza zależności pomiędzy danymi (ang. data dependence analysis) – w fazie tej identyfikuje się występujące w programie zależności danych w celu określenia części programu, które mogą być wykonywane równolegle. 2. Transformacje programu (ang. transformation techniques) - w fazie tej decydujemy, która z możliwych transformacji programu może zostać zastosowana. Istnieje wiele sposobów transformacji dostosowanych do różnych architektur oraz języków programowania. Mają one na celu takie przekształcenie programu aby zlikwidować istniejące zależności, bądź ułatwić późniejszą transformację do programu równoległego. 3. Generowanie kodu źródłowego programu równoległego (ang. code generation) - w zależności od architektury komputera oraz modelu pamięci, generowany jest kod wynikowy programu równoległego.

2 Zależności w programie
We wszystkich przedstawionych poniżej przykładach programów sekwencyjnych przyjęto założenie, że sekwencja ich wykonania jest zgodna z kolejnością ich zapisu. I tak, analizując dwie poniższe instrukcje możemy stwierdzić, że są zależne, ponieważ wynik działania drugiej z nich zależy od wyniku pierwszej. b = 2*a; c = b;

3 Zależności w programie
Zazwyczaj wyróżnia się trzy podstawowe typy zależności: Zależność właściwa lub przepływowa (ang. true/flow dependence), występuje pomiędzy dwoma instrukcjami, jeżeli pierwsza z nich zapisuje dane do komórki pamięci M, natomiast druga odczytuje oraz nie istnieje instrukcja zapisująca do M wykonywana pomiędzy nimi. Zależność tę ilustruje poniższy przykład m = a + x; b = m + c;

4 Zależności w programie
Zależność wyjściowa (ang. output dependence), występuje pomiędzy dwoma instrukcjami, jeżeli obie zapisują do tej samej komórki pamięci M oraz nie istnieje instrukcja zapisująca do M wykonywana pomiędzy nimi. Poniższe instrukcje ilustrują tę zależność m = a + x; m = b + x; Antyzależność (ang. anti-dependence), występuje pomiędzy dwoma instrukcjami, jeżeli pierwsza z nich odczytuje dane z komórki pamięci M, natomiast druga zapisuje dane do M oraz nie istnieje instrukcja zapisująca do M wykonywana pomiędzy nimi a = m + b; m = c + x;

5 Usuwanie antyzależności
Antyzależność występuje w programie, jeżeli pewna instrukcja zmienia wartość zmiennej, nie wykorzystując jej poprzedniej wartości. Usunięcie antyzależności polega na nadaniu jej nowej nazwy i wykorzystaniu w ten sposób nowego obszaru pamięci. Poniższy przykład prezentuje sposób usunięcia antyzależności względem zmiennej ”a”. b = a + c; b = a + c; a = x + y; aa = x + y; ...  ... d = a + z; d = aa + z; Napotykając dalsze odwołania do zmiennej ”a”, należy je wszystkie odpowiednio zmodyfikować,

6 Usuwanie zależności wyjściowej
Zależność wyjściową usuwa się podobnie jak antyzależność, stosując zamianę nazw zmiennych. Zależność wyjściowa występuje bowiem, gdy dwie kolejne instrukcje zmieniają wartość tej samej zmiennej, a dla wyliczenia drugiej z nich poprzednia wartość tej zmiennej nie jest istotna. a = b + c; a = b + c; a = x + y;  aa = x + y;

7 Usuwanie zależności właściwej
Zależność właściwa nie daje się usunąć całkowicie, dlatego stosowane transformacje programu mają na celu zmniejszenie liczby wystąpień takich zależności. W wielu przypadkach usuwanie zależności właściwej sprowadza się do redukcji wysokości grafu zależności (operacja ta jest znana pod nazwą redukcji wysokości drzewa). Graf zależności to graf skierowany, którego węzły reprezentują instrukcje programu, a łuki występujące pomiędzy nimi zależności. Umożliwia to częściowe zrównoleglenie obliczeń. Najczęściej stosowanymi w tym celu przekształceniami są: wprowadzenie dodatkowych zmiennych, zmiana nazw zmiennych oraz zamiana kolejności obliczeń.

8 Usuwanie zależności właściwej - przykład
a = t[1]; b = t[1] + t[2]; b = a + t[2];  c = t[3] + t[4]; c = b + t[3]; d = b + c; d = c + t[4]; Kolejne instrukcje programu wejściowego są od siebie zależne. Dwie pierwsze instrukcje zmodyfikowanego programu mogą natomiast zostać wykonane równolegle, ponieważ nie istnieje między nimi zależność – została usunięta.

9 Eliminacja zależności
for (i=1;i<=100;i=i+1) for (i=1;i<=100;i=i+1) { y[i]=x[i] / c; { t[i] =x[i] / c; x[i] = x[i] = c; x1[i] = x[i] = c; z[i] = y[i] + c; z[i] = t[i] + c; y[i] = c – y[i]; } y[i] = c – t[i]; } wyjściowa antyzależność

10 Usuwanie zależności - przykład
Rozważmy następujący przykład: Graf zależności: Mamy trzy rodzaje zależności: zależność właściwą, antyzależność oraz zależność wyjściową. St4 St1 St2 St3 dt,da,do S A1 + A2 + A3 + A

11 Usuwanie zależności - przykład
W pierwszym kroku zmieniamy nazwy zmiennych w celu eliminacji antyzależności oraz zależności właściwej, pozostała zależność właściwa St1 St2 St3 St4 dt,do St0:S0  0 St1:S1  S0 + A1 St2:S2  S1 + A2 St3:S3  S2 + A3 St4:S4  S3 + A4

12 Usuwanie zależności - przykład
Po prostych przekształceniach arytmetycznych otrzymujemy następujący „program” i graf zależności St1 St2 St3 t St1:S2  A1 + A2 St2:S3  A3 + A4 St3:S4  S2 + S3

13 Redukcja wysokości drzewa
Rozważmy następujący przykład: SUM := 0; DO 10 J := 1,8; 10: SUM := SUM + A(J);

14 Identyfikacja zależności
Czy istnieje zależność pomiędzy dwoma odwołaniami do macierzy wewnątrz pętli ? Załóżmy, że indeksy macierzy są afiniczne (jedno wymiarowa macierz jest afiniczna jeśli możemy się do niej odwołać wykorzystując wyrażenie a*i+b, gdzie a i b są stałymi oraz i jest indeksem pętli). Wynika stąd , że odpowiedź na nasze pytanie polega na sprawdzeniu czy dwie afiniczne funkcje mogą przyjmować tą sama wartość dla różnych indeksów wewnątrz zakresu pętli.

15 Identyfikacja zależności
Rozważmy następujący prosty przykład Załóżmy, że zapisujemy pewną wartość w elemencie macierzy o indeksie a*i+b oraz odczytujemy z tej samej macierzy z elementu o indeksie c*i+d, gdzie i jest indeksem pętli z zakresu od m do n. Zależność będzie istniała jeśli: Istnieją dwa indeksy pętli j i k w jej zakresie, tzn. m<= j<= n, m<=k<= n, takie, że najpierw zapisywany jest element macierzy o indeksie a*j+b a następnie odczytywany jest z macierzy element o indeksie c*k+d i a*j+b = c*k+d.

16 Identyfikacja zależności
Jak możemy rozwiązać równanie a*j+b = c*k+d ? W ogólnym przypadku nie można rozwiązać tego równania ponieważ w czasie kompilacji wartości a,b,c i d nie są znane W naszym przypadku istnieje jednak test umożliwiający sprawdzenie czy zależność istnieje czy nie. Jest to tak zwany GDE test – test największego wspólnego podzielnika Test ten bazuje na obserwacji, że tzw. loop-carried zależność istnieje jeśli GCD(c,a) dzieli (d-b) (to znaczy, że jeśli dzieli się jedną liczbę całkowitą przez drugą nie mamy reszty)

17 Identyfikacja zależności
Zastosujmy test GDC to następującego prostego przykładu: for (I=1; I<=100; I=I+1) { X[2*I+3] = x[2*I]*5.0; } Wartości wynoszą odpowiednio a = 2, b=3, c = 2 i d = 0 Stąd GDC(2,2) = 2, i d-b = -3 2 nie dzieli –3 Więc nie ma zależności

18 Wektoryzacja Proces wektoryzacji polega na przekształceniu kodu sekwencyjnego na wektorowy. Oryginalna pętla for(I=1,I<=N,I++) { A(I) = B(I) * C(I) D(I) = B(I) * K } Zmodyfikowana pętla A(I:N) = B(I:N) * C(I:N) D(I:N) = K * B(I:N)

19 Rozwijanie pętli Realizowany jest podział pętli na wiele pętli, w szczególności możemy uzyskać pełne rozwinięcie pętli w kod „sekwencyjny” ORIGINAL LOOP UNROLLED LOOP for (i=0; i == 100; i = i + 1) for (i=0; i == 99; i = i + 2) a[i] = b[i+2] * c[i-1]; { a[i] = b[i+2] * c[i-1]; a[i+1] = b[i+3] * c[i] }


Pobierz ppt "Zrównoleglanie programu sekwencyjnego"

Podobne prezentacje


Reklamy Google