Sposoby wizualizacji danych zdarzeń w poszukiwaniu problemów z wydajnością


10

Próbuję zoptymalizować aplikację MPI z wysoce asynchronicznym wzorcem komunikacji. Każda ranga ma listę rzeczy do obliczenia i wysyła wiadomości w razie potrzeby, jeśli dane wejściowe lub wyjściowe znajdują się na innej pozycji. Ponadto każda ranga jest podzielona na wątki (obecnie z jednym wątkiem komunikacyjnym i 5 pracownikami).

Oprzyrządowałem kod za pomocą timerów wokół różnych krytycznych pod względem wydajności części kodu, co daje mi listę potrójnych (początek, koniec, typ) dla każdego wątku. Wykreślone w oczywisty sposób, z czasem jako osią poziomą, rzędem i gwintem jako pionem, a kolorem wskazującym, co aktualnie robi każdy wątek, otrzymuję taki obraz dla 16 szeregów z 6 wątkami / rzędem:

Ranga i historia wątków Pentago

Moje pytanie brzmi: jakie są inne sposoby wizualizacji tych danych, które mogą pomóc w określeniu problemów z wydajnością? Czy ktoś ma ulubiony typ wykresu, którego używają podczas profilowania aplikacji asynchronicznych?

Ten zestaw danych jest ograniczony, ponieważ nie zna struktury przepływu danych, ale chciałbym uzyskać z niego jak najwięcej wglądu, zanim spróbuję zebrać coś bardziej skomplikowanego.

Bez kompresji obrazu jest tutaj w przypadku gdy ktoś chce się rozejrzeć (nie udało się załadować poprzez normalną trasą). Niestety Firefox nie akceptuje tego, chociaż uważam, że jest poprawny, być może dlatego, że jest po prostu za duży.


Miałem sporo problemów z pobraniem dużej przeglądarki przez przeglądarkę lub prawie jakikolwiek inny program. Ostatecznie gimp to zrobił, ale możesz ponownie rozważyć opcje rozmiaru lub formatu pliku.
Pedro

Przepraszam za to. Myślę, że obraz jest prawidłowy, ponieważ Firefox daje mi te same błędy, uruchamiając go przez konwersję (ImageMagick). Być może przekracza on dowolny próg wielkości.
Geoffrey Irving,

Odpowiedzi:


4

Spędzam dużo czasu na pisaniu i debugowaniu kodu równoległego, zarówno z pamięcią współdzieloną, jak i rozproszoną, ale nie znając konkretnego problemu, mogę tylko powiedzieć, co jest dla mnie najlepsze.

Wiedza, które procedury zajmują tyle czasu, jest ważna, jeśli patrzysz na wydajność obliczeniową, ale jeśli martwisz się wydajnością równoległą, powinieneś bardziej martwić się tym, co robi twój kod, gdy nie wykonuje żadnych obliczeń. Trochę martwić się tym, co robią dzieci, kiedy jest zbyt cicho ...

Ponieważ używasz hybrydowego podejścia do pamięci współużytkowanej / rozproszonej, domyślam się, że Twój kod jest, ogólnie mówiąc, albo oczekujący na wywołanie MPI, albo na zmienną mutex / condition. Możesz także zawinąć te wywołania w liczniki czasu, co da ci lepszy obraz tego, co cię spowalnia, np. Czy zawsze jest to ten sam warunek lub zawsze taki sam, w MPI_REDUCEktórym utknęły twoje wątki.

Jednym z programów, z których często korzystam, jest Intel Vtune Amplifier XE . Ma ładną funkcję / opcję drukowania, która wizualizuje współbieżność wątków. Program narysuje wykres bardzo podobny do twojego, ale gdy wątek czeka na muteks lub zmienną warunkową, rysuje ukośną linię z oczekującego wątku w momencie, w którym zaczął czekać, do wątku, który faktycznie zwolnił muteks lub zasygnalizował stan, na który czekał, w momencie zwolnienia / zasygnalizowania. Może to być dość bałagan, ale powoduje, że wąskie gardła pojawiają się natychmiast.

Na koniec zbieram również statystyki zbiorcze, np. Dla każdego wywołania muteksu / sygnału / połączenia MPI, jakie były średnie i maksymalne czasy oczekiwania? Jaki jest histogram zebranych czasów oczekiwania? Chociaż fabuła daje ładny przegląd, może być dość niechlujna, jeśli chodzi o drobne szczegóły.

Na koniec jedno pytanie, którego nie należy lekceważyć: Jak zbierasz swoje czasy? Czy Twój czasomierz jest wystarczająco nieinwazyjny, aby nie wpływać na kod? Korzystam z instrukcji CPU, ilekroć jest to możliwe, tj. RDTSCNa architekturach x86. Zwykle dodaje to tylko jedną instrukcję do kodu.


Dane mają już bloki wokół wszystkich oczekiwań; na schemacie są pokazane jako białe dla wątków roboczych bezczynnych i żółte dla oczekujących wątków komunikacyjnych. Niestety, wszystkie oczekiwania w wątku komunikacyjnym występują w jednym kocu MPI_Waitsome ze względu na asynchronię. Vtune nie ma zastosowania w tym przypadku, ponieważ czysto wątkowa wydajność jest zasadniczo idealna, ale dzięki za wskaźnik. Sugestia histogramowa też jest dobra.
Geoffrey Irving,

Co do narzutu czasowego: używam gettimeofday, co jest konieczne przynajmniej w okolicach bezczynnych sekcji, ponieważ tam używam zmiennych warunku pthread. Czy można liczyć, że instrukcje procesora będą działały w takiej sytuacji? Koszty ogólne są już wystarczająco niskie, ale niższe z pewnością byłyby ładniejsze.
Geoffrey Irving,

1
@GeoffreyIrving: Tak, możesz ich używać, ale mają one sens tylko na procesorach, które mają constant_tscustawioną flagę (zaznacz /proc/cpuinfo) i jeśli użyjesz zablokowania każdego wątku do określonego rdzenia, tzn. Każdy wątek zawsze czyta ten sam rejestr z tego samego rdzenia, np pthread_setaffinity_np. za pomocą . Pamiętaj, że ten ostatni jest specyficzny dla Linuksa i dlatego nie jest przenośny.
Pedro

@GeoffreyIrving: Nawet jeśli czekasz na jakieś nieujawnione zdarzenie przy użyciu MPI_Waitsome, możesz nadal rejestrować, które żądania faktycznie dotarły i skąd. Informacje te mogą, ale nie muszą być przydatne ...
Pedro

5

Czasami można uzyskać alternatywny pogląd na problemy z wydajnością za pomocą analizy zasobów wysokiego poziomu: Czy istnieje istotne wąskie gardło, takie jak przepustowość pamięci? Czy każdy wątek roboczy wykonuje taką samą ilość pracy? Dane te można łatwo zebrać za pomocą likwid-perfctr z pakietu narzędzi LIKWID Google Code project . Jeśli profil jest taki, że istnieje wiele różnych gorących punktów, konieczne może być zajęcie się nimi pojedynczo. Mogą występować również różne problemy, w zależności od liczby używanych wątków / procesów.


W trosce o idealne ujawnienie Georg pracuje nad projektem LIKWID i poprosiłem o tę odpowiedź, ponieważ chciałem uzupełnić świetną odpowiedź Pedro inną perspektywą (i doskonałym, darmowym narzędziem).
Aron Ahmadia,

2

Kiedy mam problem w sieci wysoce asynchronicznych procesów zarządzanych przez komunikaty lub zdarzenia, używam metody, która nie jest łatwa, ale skuteczna. Wymagało to pobrania dzienników procesów ze znacznikami czasu, scalenia ich we wspólną oś czasu i śledzenia postępu niektórych wiadomości, gdy wyzwalają działania, wyzwalając kolejne wiadomości. To, czego szukam, to opóźnienie między momentem odebrania wiadomości a momentem, w którym podjęto działanie, i zrozumienie przyczyny opóźnienia. Gdy problem zostanie znaleziony, zostaje rozwiązany, a proces jest powtarzany. W ten sposób możesz uzyskać naprawdę satysfakcjonującą wydajność.

Ważne jest, aby zobaczyć, jak różni się to od podejść, w których mierzysz, mierzysz, mierzysz. Jedyne, co można mierzyć, może powiedzieć, gdzie nie patrzeć. Prawdziwe dostrajanie wydajności wymaga uważnego spojrzenia na szczegóły z perspektywy czasu. Czego szukasz, to nie gdzie spędzasz czas, ale gdzie spędzasz go niepotrzebnie.

Powodzenia.


Innymi słowy, nie ma użytecznej wizualizacji danych, które posiadam. :) Jed Brown zasugerował Jumpshot (i powiązane narzędzia) jako jeden ze sposobów gromadzenia i wizualizacji sugerowanych danych, więc przyjrzę się temu.
Geoffrey Irving,

@Geof: Powodzenia w wizualizacji. Jedynym narzędziem, które uznałem za przydatne, jest gromadzenie i scalanie dzienników zdarzeń, dzięki czemu mogłem podążać ścieżką jednego lub większej liczby żądań, gdy przechodziło przez różne wątki, ponieważ jest to jedyny znany mi sposób na wykrycie niepotrzebnego opóźnienia Na tym polega każdy problem z wydajnością - niepotrzebne opóźnienia.
Mike Dunlavey,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.