Zadanie 1 - Macierze OMP

Transkrypt

Zadanie 1 - Macierze OMP
Zofia Sobocińska
19/11/2013
Zadanie 1 - Macierze OMP
Mnożenie i dodawanie dwóch macierzy kwadratowych
Programy z zadania pierwego mają dwa zadania: mnożenie i dodawanie dwóch macierzy: AN xN iBN xN . W celu uzyskania równoległości należało dopisać dyrektywę preprocesora wymaganą do działania OpenMP, przykładowo dla mnożenia macierzy:
1
2
3
4
5
6
7
8
#pragma omp p a r a l l e l f o r
f o r ( s i z e t i = 0 ; i < s i z e ; i ++)
f o r ( s i z e t j = 0 ; j < s i z e ; j ++) {
C[ i ] [ j ] = 0 ;
f o r ( s i z e t k = 0 ; k < s i z e ; k++)
C [ i ] [ j ] += A[ i ] [ k ] ∗ B [ j ] [ k ] ;
}
}
Początkowo macierze przechowywane były w tablicy jednowymiarowej (wiersz za
wierszem), jednak krótkie czasy operacji dodawania (przy wymaganym czasie poniżej 2s)
zmusiły do operowania na danych znacznie przekraczających maksymalny rozmiar tablicy
jednowymiarowej.
Zarówno dodawanie, jak i mnożenie
macierzy, opierają się na najprostszych algorytmach: w mnożeniu dla każdej komórki
każdego wiersza cm,n liczona jest suma iloczynów odpowiednich komórek macierzy
P
wejściowych A i B: cm,n = N
i=1 am,i · bi,n .
Sumowanie następuje w pętli. Dla dodawania iterujemy po każdej komórce każdego
wiersza cm,n i przypisujemy mu sumę koRysunek 1: Zależność czasu obliczeń od liczby
mórek macierzy A i B o tych samych inwątków - mnożenie macierzy
deksach: cm,n = am,n + bm,n .
Program został uruchomiony na maszynie 4-rdzeniowej z Hyper-Threadingiem
w 11-tu konfiguracjach - po 5 razy
dla liczby wątków 1-10 i 5 razy dla
liczby wątków automatycznie przyjętej
przez OpenMP. (standardowo jest to liczba
rdzeni) Zmierzony został średni czas obliczeń w każdej z tych konfiguracji.
Sumowanie jest wprawdzie znacznie mniej czasochłonne (dla dodawania Rysunek 2: Zależność czasu obliczeń od liczby
wątków - dodawanie macierzy
CN,N = AN xN + BN xN składa się na nie
N × N operacji sumowania; dla porównania, mnożenie macierzy wymaga dla każdej komórki (N × N komórek) N operacji dodawania i N operacji mnożenia). Dla odpowiednio
dużych danych obserwujemy jednak wyraźne przyśpieszenie. Równocześnie nie występuje
tam problem zależności danych ani sterowania, problem daje się zatem łatwo zrównoleglić
z uniknięciem narzutu związanego z synchronizacją wątków.
1
Sterowanie zachowaniem OpenMP
Dyrektywa:
1
#pragma omp p a r a l l e l f o r d e f a u l t ( s h a r e d )
ma zachowanie zgodne z domyślnym. Wszystkie zmienne (za wyjątkiem prywatnych iteratorów pętli) uznawane są za dzielone.
W poniższej postaci
1
#pragma omp p a r a l l e l f o r d e f a u l t ( none ) s h a r e d (A, B, C) f i r s t p r i v a t e ( r o z m i a r
) private ( i , j )
własnoręcznie wskazujemy zachowanie OpenMP w stosunku do określonych zmiennych.
Możemy bez obaw dzielic zmienne wskaźników na macierze, ponieważ zawartości A i B
nie modyfikujemy, natomiast w tablicy C każdy wątek modyfikuje odrębne komórki - nie
ma obawy, że jeden z wątków nadpisze wynik pracy innego. Firstprivate wskazuje nam, że
zmienna rozmiar ma zasięg prywatny dla każdego wątku, ale inicjalizowana jest wartością
zmiennej rozmiar z wątku głównego.
Istotne przy mierzeniu czasu wykonania było uniknięcie funkcji clock() - zwraca
liczy ona bowiem liczę taktów CPU, a w sytuacji obliczeń wielowątkowych sumaryczny
czas tych taktów będzie nie mniejszy niż przy jednowątkowych obliczeniach. Dodatkowo
pojawi się narzut czasowy związany ze zrównolegleniem i pozorny wynik będzie wprost
przeciwny do oczekiwanego.
Wśród zalet zrównoleglenia z wykorzystaniem technologii OpenMP możemy wymienić:
• Prostotę użycia - implementacja programów opartych na OpenMP nie wymaga specjalistycznej wiedzy,
• Znaczne przyśpieszenie czasu obliczeń (co widać na wykresie),
• Możliwość wprowadzenia własnych modyfikacji do strategii zrównoleglenia.
Podsumowanie
Środowisko uruchomieniowe oddało
aplikacji do dyspozycji 4 rdzenie w technologii Hyper-Threading. Czas wykonywania się mnożenia macierzy wciąż spadał
gdy wykorzystane zostały wszystkie CPU
- fizyczne i wirtualne, a więc zysk przyniosło również współbieżne wykonanie się
wątków.
Czas wykonywania się dodawania
macierzy spada mniej stabilnie. Wprawdzie Rysunek 3: Wykres przyśpieszenia (przykład dla
mnożenia macierzy)
na każdą operację arytmetyczną przypada
kilka odniesień do pamięci, nie występują tu jednak zależności danych, dzięki czemu program ładnie się zrównolegla.
Własnoręczne wskazywanie liczby wątków jest jednak w większości przypadków zbyteczne, ponieważ automatycznie dobrana ich liczba (zazwyczaj równa liczbie rdzeni) okazuje się najbardziej optymalna.
2

Podobne dokumenty