• Nie Znaleziono Wyników

Analiza i modelowanie wydajności obliczeńLab 9. Model wydajności "roofline" Cel: Analiza wydajności wybranego algorytmu korzystając z modelu wydajności "roofline".Kroki:1.Rozpakuj paczkę

N/A
N/A
Protected

Academic year: 2021

Share "Analiza i modelowanie wydajności obliczeńLab 9. Model wydajności "roofline" Cel: Analiza wydajności wybranego algorytmu korzystając z modelu wydajności "roofline".Kroki:1.Rozpakuj paczkę"

Copied!
4
0
0

Pełen tekst

(1)

Analiza i modelowanie wydajności obliczeń Lab 9. Model wydajności "roofline"

Cel: Analiza wydajności wybranego algorytmu korzystając z modelu wydajności "roofline".

Kroki:

1. Rozpakuj paczkę mat_vec_optimization.tgz w nowym katalogu np. lab_09, ewentualnie wykorzystaj pliki z poprzedniego laboratorium (w dalszym opisie założone jest korzystanie z dostarczonej paczki – własne modyfikacje można wprowadzać do plików z paczki)

2. Zmodyfikuj plik Makefile wybierając jeden z kompilatorów i uruchom program w wersji bez register blocking i cache blocking (w pliku mat_vec.c)

3. Po przetestowaniu poprawności działania wykomentuj fragment realizujący sprawdzenie wyniku w pliku mat_vec_test.c (linie 31-50, cały kod jest specjalnie uproszczony, żeby ułatwić późniejsze pomiary)

4. Oblicz liczbę operacji algorytmu oraz liczbę dostępów do pamięci (wzorując się także na wynikach poprzedniego laboratorium):

• oblicz osobno liczbę dostępów dla pliku mat_vec_test.c i osobno dla mat_vec.c

• liczba dostępów w całym programie (jako suma powyższych) składa się z liczby zapisów i odczytów, liczba zapisów jest jednoznacznie określona przez

inicjowanie tablicy a i wektora x (w pliku mat_vec_test.c) oraz jednokrotny zapis do wektora y (w pliku mat_vec.c), natomiast liczba odczytów jest jednoznacznie określona dla a, a dla x zależy od sposobu traktowania x (od tego jaka jest liczba transferów elementów wektora x pomiędzy pamięcią DRAM i różnymi poziomami pamięci podręcznej w trakcie wykonania algorytmu)

Wskazówka – obliczenie liczby operacji i dostępów do pamięci w pliku mat_vec_test.c (po wykomentowaniu sprawdzenia poprawności wyniku):

◦ linia 19 – ROZMIAR = WYMIAR*WYMIAR zapisów do a (data write operation)

◦ linia 20 – WYMIAR zapisów do x (data write operation)

5. Na podstawie obliczonych liczb zapisów i odczytów, oblicz intensywność

arytmetyczną algorytmu mnożenia macierz-wektor (plik mat_vec.c) posługując się założeniami dotyczącymi traktowania x

◦ w sprawozdaniu opisz poczynione założenia i ich wpływ na obliczoną intensywność arytmetyczną

6. Uruchom program pod kontrolą narzędzia valgrind (uwaga: valgrind jest rodzajem symulatora, czas wykonania jest wielokrotnie dłuższy niż standardowy):

valgrind --tool=cachegrind ./mat_vec_test_opt.exe

◦ zaobserwuj zwracane wyniki w kategoriach dotyczących danych (dostępy związane z kodem – rozkazami, instructions, I – w tak krótkim programie są bez znaczenia) :

▪ D refs (data references) – liczba rozkazów dostępów do pamięci w

asemblerze (uwaga na liczbę danych w pojedynczym rozkazie – patrz poniżej)

▪ D1 misses – liczba chybień w pamięci L1

▪ LLd misses – liczba chybień w pamięci L3 (last level cache)

7. Zweryfikuj obliczenia liczby dostępów do pamięci w algorytmie za pomocą wyników z eksperymentu, uwzględniając następujące fakty:

• dostępy do pamięci (data references) mogą być realizowane przez operacje wektorowe – jako pierwszy etap należy określić ilu dostępom do wartości

(2)

skalarnych odpowiada jeden dostęp raportowany przez valgrind, można do tego użyć np. kod asemblera dla badanej wersji (gcc (icc) -S -O3 mat_vec.c)

[np. movsd jest rozkazem dotyczącym pobrania jednej wartości 64-bitowej do rejestru xmm, natomiast movapd, movaps, movups, movupd mogą pobierać 2, 4 lub 8 wartości – należy sprawdzać adresy i rejestry, których dotyczą]

• chybienie w pamięci oznacza pobranie całej linii, a więc kilku elementów tablicy (standardowo byłoby to 8 elementów double)

• w algorytmie mnożenia macierz-wektor (plik mat_vec.c) występują odczyty i zapisy - te ostatnie tylko dla wektora y,

• w pozostałej części programu (plik mat_vec_test.c) występują wyłącznie zapisy (inicjowanie a i x) – wyniki raportowane przez valgrind dla odczytów bezpośrednio dotyczą więc algorytmu mnożenia macierz-wektor, natomiast w przypadku

zapisów należy od liczb raportowanych przez valgrind odjąć wartości obliczone dla mat_vec_test.c

• obliczona liczba dostępów do pamięci DRAM powinna być równa liczbie chybień w pamięci L3 (LLC – last level cache)

◦ ile chybień pojawiło się ze względu na odczyty x ? (jako różnica całkowitej liczby chybień i liczby chybień ze względu na a – z powodu braku lokalności czasowej i pełnej lokalności przestrzennej chybienie następuje dla

(standardowo) co ósmego wyrazu a)

◦ ile razy wektor x był pobierany z DRAM do L3?

• dla bardziej dokładnego obliczenia wydajności algorytmu ważna jest także liczba chybień w pamięci L1

◦ różnica między liczbą chybień w L1 i L3 to liczba trafień w L2 lub w L3

◦ ile chybień pojawiło się ze względu na odczyty x ? (jako różnica całkowitej liczby chybień i liczby chybień ze względu na a – z powodu braku lokalności czasowej i pełnej lokalności przestrzennej chybienie następuje dla

(standardowo) co ósmego wyrazu a)

◦ ile razy wektor x był pobierany z L3 (lub L2) do L1?

8. Ustal ostateczną wartość intensywności arytmetycznej dla badanego kodu 9. Na podstawie wyników poprzednich laboratoriów skonstruuj diagram roofline

platformy, na której dokonywane są obliczenia (dla obliczeń jednowątkowych). Na diagramie zaznacz linie odpowiadające teoretycznym maksimom i wynikom

uzyskanym w testach (w sprawozdaniu podaj z jakich testów korzystasz). Zaznacz pionową linię odpowiadającą intensywności arytmetycznej algorytmu mnożenia macierz-wektor.

10. Uruchom program i zmierz czas wykonania – oblicz wydajność w GFLOP/s. Wynik nanieś na diagram roofline.(uwaga: wydruk programu podaje czas wykonania wyłącznie funkcji mnożenia macierz-wektor)

11. Dokonaj zrównoleglenia kodu poprzez wstawienie dyrektywy

#pragma omp parallel for default(none) shared(a,x,y,n) private(j) przed zewnętrzną pętlą (pamiętaj o modyfikacji odpowiednich opcji w pliku Makefile, np. -fopenmp dla gcc, -qopenmp dla icc, efekt wykonania wielowątkowego sprawdź np. za pomocą htop)

◦ zrównoleglenie może dotyczyć dowolnej poprawnej wersji kodu

12. Przeprowadź obliczenia dla różnej liczby wątków stosując zmienną środowiskową OMP_NUM_THREADS. Odnotuj czas wykonania algorytmu mnożenia macierz wektor, oblicz parametry skalowalności w sensie silnym i wydajność w GFLOP/s (a także w GB/s, na podstawie przyjętej wartości intensywności arytmetycznej). Wyniki wpisz do tabeli. (dla każdej liczby wątków należy obliczenia powtórzyć kilka razy i

(3)

wybrać najkrótszy czas, można także eksperymentować z przypisaniem wątków do rdzeni):

Liczba procesorów 1 2 4 10 20 40 itd.

Czas wykonania

Przyspieszenie obliczeń Efektywność zrównoleglenia Wydajność [GFLOP/s]

Wydajność [GB/s]

13. Skonstruuj wykresy wydajności, czasu wykonania, przyspieszenia obliczeń i efektywności obliczeń jako funkcji liczby wątków (wykres przyspieszenia obliczeń powinien w swoim charakterze odpowiadać odpowiednio przeskalowanemu

wykresowi wydajności w GFLOP/s, ze względu na podstawową relację: wydajność jako odwrotność czasu wykonania). Wyciągnij wnioski z charakteru wykresów i umieść je w sprawozdaniu.

14. Na podstawie wyników poprzednich laboratoriów skonstruuj diagram roofline platformy, na której dokonywane są obliczenia – tym razem dla obliczeń

wielowątkowych, pokazujący pełny potencjał sprzętu. Na diagramie zaznacz linie odpowiadające teoretycznym maksimom i wynikom uzyskanym w testach (w sprawozdaniu podaj z jakich testów korzystasz). Zaznacz pionową linię

odpowiadającą intensywności arytmetycznej algorytmu mnożenia macierz-wektor.

15. Wybierz z tabeli wynik o najlepszej wydajności i nanieś go na diagram roofline.

Dalsze kroki:

1. Przeprowadź optymalizację register blocking dla algorytmu mnożenia macierz-wektor w wersji jednowątkowej. Dla zoptymalizowanego algorytmu uruchom program pod kontrolą valgrind i zaobserwuj różnice w liczbie dostępów, trafień i chybień w pamięciach podręcznych różnych poziomów w porównaniu z wersją bez optymalizacji.

1. Zweryfikuj wpływ optymalizacji na wydajność uruchamiając program w sposób standardowy (np. za pomocą make, bez użycia valgrind). Porównaj z wydajnością bez register blocking.

2. Wyciągnij wnioski dotyczące dostępów do pamięci, w szczególności dla wektora x – gdzie przechowywany jest w trakcie obliczeń?, jaka jest liczba transferów

między różnymi poziomami pamięci podręcznej dla elementów wektora x? jaki ma to wpływ na wydajność?

2. Zweryfikuj wyniki dotyczące liczby dostępów do pamięci dla różnych wersji programu korzystając z interfejsu PAPI i liczników sprzętowych (uwaga: przy doborze liczników sprzętowych należy zwracać uwagę na zliczanie dostępów pobierania z

wyprzedzeniem przez procesor (hardware prefetching), w algorytmie większość dostępów może być realizowana w ten właśnie sposób). Do realizacji tego zadania można wykorzystać, dowolnie modyfikując, zawartość paczki

mat_vec_optimization_papi.tgz.

3. Przeprowadź badanie skalowalności dla wersji mnożenia macierz-wektor bez optymalizacji

◦ zaobserwuj lepszą skalowalność tej wersji od wersji zoptymalizowanej –

potwierdzając wniosek, że z wielowątkowości często bardziej korzystają programy

(4)

mniej optymalne, w wersji jednowątkowej gorzej wykorzystujące możliwości oferowane przez sprzęt

4. Jeśli wyniki wydajnościowe dla najlepszej dotychczasowej wersji kodu odbiegają znacząco od "linii dachu" na diagramie roofline zastanów się nad możliwymi przyczynami tego zjawiska oraz możliwymi dalszymi optymalizacjami kodu, które pozwoliłyby na zwiększenie wydajności. Spróbuj przeprowadzić te optymalizacje, zanotuj otrzymane wyniki i wyciągnij odpowiednie wnioski.

Sprawozdanie:

1. Zrealizowane kroki, najważniejsze fragmenty modyfikowanego kodu (a także

ewentualnie uzyskiwanego asemblera), spostrzeżenia z analizy kodu (i ewentualnie odpowiadającego kodu asemblera), tabele, wykresy, opisy, wnioski

Cytaty

Powiązane dokumenty

Tabela 2 przedstawia średnie wyniki pomiarów uzyskane w testach wydajności maszyn wirtualnych w wirtualizatorze ESXi 6.5.0 dla scenariuszy testowych

Na podstawie literatury i przedstawionych wcześniej klasyfikacji Plebankiewicz, Juszczyk i Malara (2014) dokonali identyfikacji czynników wpływających na wydajność pracy

Analizę wydajności środków transportu dystrybutora gazu płynnego przeprowadzono dla wykonanej trasy przewozowej czterech pojazdów rozwożących butle gazowe podczas

(3) Jeśli w wyznaczonym 2 - elementowym ciągu element prawy jest elementem dodanym lub element prawy jest różny od klucza, nie znaleziono elementu równego kluczowi-zwróć 0,

(3) Jeśli w wyznaczonym 2 - elementowym ciągu element prawy jest elementem dodanym lub element prawy jest różny od klucza, nie znaleziono elementu równego

kompilator jest inny, inne są też czasy wykonania. Ćwiczenie obejmuje analizę kodu asemblera – kompilator gcc produkuje prostszy kod asemblera, kompilator icc umieszcza w

Kod funkcji (podobnie jak kod w mat_mul_avx_1) jest tak napisany, żeby stanowić wskazówkę, jak dokonać optymalizacji. Optymalizacja w mat_mul_avx_2 może dotyczyć dwóch

Oprawa oświetleniowa LED do wbudowania PowerBalance gen2 RC462B/RC463B ze sterownikiem ActiLume, rozmiar modułu 625 (wersja do sufitów z widocznymi profilami). Oprawa oświetleniowa