Profilowanie kodu CFD za pomocą Callgrind

16

Używam Valgrind + Callgrind do profilowania napisanego przeze mnie solwera. Jak stwierdza instrukcja obsługi Valgrind, skompilowałem swój kod z opcjami debugowania dla kompilatora:

„Bez informacji o debugowaniu najlepsze narzędzia Valgrind, które można zrobić, to odgadnięcie, do której funkcji należy dany fragment kodu, co sprawia, że ​​zarówno komunikaty o błędach, jak i wyniki profilowania są prawie bezużyteczne. Dzięki opcji -g otrzymasz wiadomości wskazujące bezpośrednio na odpowiednie wiersze kodu źródłowego. ”

Podręcznik Valgrind

Po skompilowaniu z opcją debugowania kody działają znacznie wolniej. Kod CFD staje się NAPRAWDĘ powolny, nawet w małych przypadkach po skompilowaniu z flagami debugowania. Valgrind sprawia, że ​​jest 40 razy wolniejszy (patrz instrukcja 1 ).

  1. Jakich narzędzi używasz do profilowania kodu (profilowanie, a nie benchmarking)?

  2. Jak długo pozwalasz na działanie kodu (statystyki: ile kroków czasowych)?

  3. Jak duże są przypadki (jeśli sprawa mieści się w pamięci podręcznej, solver jest o rząd wielkości szybszy, ale wtedy przegapię procesy związane z pamięcią)?

tmaric
źródło
3
Możesz skompilować kod z włączonymi symbolami debugowania i optymalizacją. Mimo to 40x przez valgrind (który symuluje cały dostęp do pamięci) nie jest nierozsądne.
Aron Ahmadia
Dzięki, to też przeczytałem ... Chciałbym wiedzieć o codziennych doświadczeniach w profilowaniu (najlepiej z valgrind): ile czasu normalnie czekać na raporty, ile iteracji liczy się to, czego potrzebuję, co mogę wykluczyć ... itd.
tmaric
Twoje pytanie jest również nieco ogólne. Zalecam edycję pytania, aby skupić się na Q2.1 i Q2.2, ponieważ Q1 jest zupełnie innym pytaniem (cieszę się, że możesz zadać je osobno, jest dobre, ale sformułuj je jako „Jakie narzędzia byś zrobił? użyj, aby rozwiązać problem X ”, gdzie X jest dobrze opisany!), podczas gdy sam Q2 jest zbyt ogólny.
Aron Ahmadia
Można również zmieniać nazwy callgrind, cachegrindlub massif. Wiele osób kojarzy Valgrind tylko z domyślnym narzędziem ( memcheck). Jako system profilowania oparty na emulacji (a nie na przerwie) nie trzeba długo uruchamiać.
Jed Brown
@Aron & Jed: dzięki za wskazówki, zredagowałem pytanie. :)
tmaric

Odpowiedzi:

11

P1: Jakich narzędzi używasz do profilowania kodu (profilowanie, a nie testowanie wydajności)?

P2: Jak długo pozwalasz na działanie kodu (statystyki: ile kroków czasu)?

P3: Jak duże są przypadki (jeśli sprawa mieści się w pamięci podręcznej, solver jest o rząd wielkości szybszy, ale wtedy przegapię procesy związane z pamięcią)?

Oto przykład tego, jak to robię.

Oddzielam testy porównawcze (sprawdzanie, jak długo to potrwa) od profilowania (identyfikowanie, jak przyspieszyć). Nie jest ważne, aby profiler był szybki. Ważne jest, aby informował o tym, co naprawić.

Nie podoba mi się nawet słowo „profilowanie”, ponieważ wyczarowuje obraz coś w rodzaju histogramu, w którym dla każdej procedury istnieje pasek kosztów, lub „wąskie gardło”, ponieważ oznacza, że ​​w kodzie jest tylko trochę miejsca, które musi być naprawiony. Obie te rzeczy oznaczają pewien czas i statystyki, dla których, jak zakładasz, ważna jest dokładność. Nie warto rezygnować z wglądu w dokładność pomiaru czasu.

Zastosowanie metody I jest przypadkowe zatrzymywanie, a tam pełne studium przypadku i pokaz slajdów tutaj . Częścią światopoglądu wąskiego gardła profilera jest to, że jeśli niczego nie znajdziesz, nic nie można znaleźć, a jeśli coś znajdziesz i uzyskasz określony procent przyspieszenia, ogłaszasz zwycięstwo i rezygnujesz. Fani Profiler prawie nigdy nie mówią, ile przyspieszają, a reklamy pokazują tylko sztucznie wymyślone problemy, które można łatwo znaleźć. Losowe wstrzymywanie powoduje znalezienie problemów, czy są one łatwe, czy trudne. Następnie naprawienie jednego problemu ujawnia inne, dzięki czemu proces można powtórzyć, aby uzyskać złożone przyspieszenie.

Z mojego doświadczenia wynikającego z wielu przykładów, oto jak to wygląda: mogę znaleźć jeden problem (przez losowe wstrzymanie) i naprawić go, uzyskując przyspieszenie o pewien procent, powiedzmy 30% lub 1,3x. Następnie mogę to zrobić ponownie, znaleźć inny problem i rozwiązać go, otrzymując kolejne przyspieszenie, może mniej niż 30%, może więcej. Potem mogę to zrobić wiele razy, dopóki naprawdę nie znajdę nic innego do naprawienia. Ostateczny współczynnik przyspieszenia jest działającym iloczynem poszczególnych czynników i może być niesamowicie duży - w niektórych przypadkach rzędu wielkości.

WSTAWIONO: Aby zilustrować ten ostatni punkt. Jest to szczegółowy przykład tutaj , z pokazu slajdów i wszystkich plików, pokazując, jak przyspieszenie od 730X został osiągnięty w serii problemowych przeprowadzek. Pierwsza wersja zajęła 2700 mikrosekund na jednostkę pracy. Problem A został usunięty, co skróciło czas do 1800 i zwiększyło odsetek pozostałych problemów o 1,5x (2700/1800). Następnie B został usunięty. Proces ten trwał przez sześć iteracji, co spowodowało przyspieszenie prawie 3 rzędów wielkości. Ale technika profilowania musi być naprawdę skuteczna, ponieważ jeśli którykolwiek z tych problemów nie zostanie znaleziony, tj. Jeśli dojdziesz do punktu, w którym błędnie myślisz, że nic więcej nie można zrobić, proces zatrzymuje się.

Opis usuwania wielu problemów, aby uzyskać duże przyspieszenie

WSTAWIONO: Innymi słowy, oto wykres współczynnika całkowitego przyspieszenia po usunięciu kolejnych problemów:

wprowadź opis zdjęcia tutaj

Tak więc w pierwszym kwartale do przeprowadzenia testu porównawczego wystarczy prosty licznik czasu. Do „profilowania” używam losowego wstrzymywania.

Q2: Daję mu wystarczającą ilość pracy (lub po prostu owinąć pętlę), aby działał wystarczająco długo, aby zatrzymać.

P3: Zapewnij realistycznie duże obciążenie pracą, aby nie przegapić problemów z pamięcią podręczną. Będą one wyświetlane jako próbki w kodzie wykonującym pobieranie pamięci.

Mike Dunlavey
źródło
Mike, czy wolisz robić losowe pauzy przy braku wizualnego IDE? Czy proces ten można w jakiś sposób zautomatyzować?
Matthew Emmett
@Matthew: Rozumiem, że istnieją narzędzia takie jak pstacki lsstack, ale naprawdę uważam, że jest to proces bardziej podobny do debugowania. Więc nawet jeśli najlepszym debugerem, jaki mogę przynieść, jest gdbto zadanie. Za pomocą debugera możesz badać dane, co może mieć znaczenie, gdy sam stos nie powie ci wystarczająco dużo.
Mike Dunlavey
9

W profiler biedaka jest w zasadzie gdbskrypt próbek stos wywołań. Nadal musisz mieć symbole debugowania. Nadal jest wolny, ale ponieważ nie implementuje maszyny wirtualnej do uruchomienia kodu, jest często szybszy callgrindi adekwatny do zadania.

Wpadłem na analizatory fizyki cząstek ze skromnym sukcesem (tj. Pokazałem, że kod nie ma żadnych strasznych punktów krytycznych, a optymalizacja wymagałaby lepszego algorytmu).

dmckee --- były kot moderator
źródło
1
+ Brak dowodów nie jest dowodem nieobecności :) To, co powinien zrobić profilujący tego biednego człowieka, to pobrać mniej śladów i nie zawalać ich, ale pozwól im je zobaczyć. Ludzkie oko jest znacznie lepsze w wykrywaniu użytecznych wzorców niż proste szacunki czasu działania, a jeśli zobaczysz coś, co można poprawić na zaledwie 2 próbkach, pomoże to znacznie. Ułamek X, który zaoszczędzi, to rozkład beta w trybie 2 / N, gdzie N to liczba zbadanych śladów, a współczynnik przyspieszenia wyniesie 1 / (1-X), co może być duże.
Mike Dunlavey,
2

Aby dodać do dostępnych świetnych odpowiedzi, w Rice opracowano narzędzie, które automatyzuje próbkowanie stosu, a zatem ma bardzo mały narzut:

http://hpctoolkit.org/

Reid.Atcheson
źródło
To ładnie wygląda, choć (przepraszam) założyłem tutaj swój płomienny kapelusz. Nie dostrajam się do kodu zoptymalizowanego przez kompilator, ponieważ trudno jest zobaczyć, co się dzieje w zniekształconym kodzie. To, co przycinam, nie jest tym, z czym optymalizator mógłby sobie poradzić - jak wywołanie expi logpowtarzanie tych samych argumentów lub operacje matrycy spędzające cały czas na opcjach dekodowania. Stroję tak daleko, jak to możliwe, a następnie włączam -O3.
Mike Dunlavey,
Narzędzia są narzędziami i są użyteczne tylko wtedy, gdy użytkownik zna i rozumie ich ograniczenia. Nie sądzę, że kiedykolwiek pojawi się „idealny profiler”, który całkowicie usunie użytkownika z równania, jeśli chodzi o zrozumienie jego wyników i umiejętność korzystania z informacji.
Reid.Atcheson
1

Allinea MAP to komercyjnie opracowany i obsługiwany profiler próbkowania, a zatem - jak sugeruje wcześniejsza wersja HPC Toolkit - może działać na zleceniach o wielkości produkcyjnej, jeśli chcesz.

Tego rodzaju narzędzie wskazuje na wąskie gardła procesora lub słabą komunikację MPI, ale cały nadzór nad profilowaniem całego zadania może być bezcenny w poszukiwaniu niespodzianek.

Często pojawiają się nisko zawieszające się owoce, które znajdują się poza rdzeniem jądra kodu CFD, w obszarach, których nie oczekiwano. Losowe próbkowanie stosu jest - czy to ręcznie przy pomocy GDB, czy przy pomocy narzędzi takich jak HPC Toolkit i Allinea MAP - najlepszy sposób na ich znalezienie. Jeśli coś jest ważne dla wydajności, pojawi się.

David
źródło