Opowieść hakera
Data to 02.12.10. Dni przed Bożym Narodzeniem ociekają i jako programista Windows natrafiłem na poważną blokadę. Używałem AQTime, próbowałem śpiący, błyszczący i bardzo senny, a kiedy mówimy, VTune instaluje. Próbowałem użyć profilera VS2008, który był pozytywnie karany, a także często niewrażliwy. Użyłem techniki pauzy losowej. Zbadałem drzewa połączeń. Odpaliłem ślady funkcji. Ale smutnym i bolesnym faktem w tej sprawie jest to, że aplikacja, z którą pracuję, składa się z ponad miliona linii kodu, z prawdopodobnie kolejnym milionem linii aplikacji innych firm.
Potrzebuję lepszych narzędzi. Przeczytałem inne tematy. Wypróbowałem każdy profiler wymieniony w każdym temacie. Po prostu musi być coś lepszego niż te niezdarne i drogie opcje lub absurdalne ilości pracy, która prawie bez zysku. Aby jeszcze bardziej skomplikować sprawę, nasz kod jest mocno podzielony na wątki i uruchamia szereg pętli zdarzeń Qt, z których niektóre są tak delikatne, że ulegają awarii przy dużym obciążeniu instrumentalnym z powodu opóźnień czasowych. Nie pytaj mnie, dlaczego uruchamiamy wiele pętli zdarzeń. Nikt nie może mi powiedzieć.
Czy są jakieś inne opcje podobne do Valgrind w środowisku Windows?
Czy jest coś lepszego niż długi pas zepsutych narzędzi, które już wypróbowałem?
Czy jest coś zaprojektowanego do integracji z Qt, być może z użytecznym wyświetlaniem zdarzeń w kolejce?
Pełna lista narzędzi, które wypróbowałem, z tymi, które były naprawdę przydatne, zapisana kursywą:
- AQTime: Raczej dobrze! Ma pewne problemy z głęboką rekurencją, ale wykres wywołań jest poprawny w takich przypadkach i może być użyty do wyjaśnienia wszelkich nieporozumień. Nie jest to idealne narzędzie, ale warte wypróbowania. Może pasować do twoich potrzeb i na pewno wystarczało mi przez większość czasu.
- Atak z przypadkowym wstrzymaniem w trybie debugowania: za mało informacji w czasie.
Dobre narzędzie, ale nie kompletne rozwiązanie. - Parallel Studios: opcja nuklearna. Natarczywy, dziwny i szalenie potężny. Myślę, że powinieneś zaliczyć 30-dniową ocenę i dowiedzieć się, czy jest to dobre dopasowanie. To też jest cholernie fajne.
- AMD Codeanalyst: Wspaniały, łatwy w użyciu, bardzo podatny na awarie, ale myślę, że to kwestia środowiska. Polecam go wypróbować, ponieważ jest bezpłatny.
- Luke Stackwalker: Działa dobrze w małych projektach, trochę próbuję sprawić, by działało na naszych. Jednak dobre wyniki i zdecydowanie zastępuje Sleepy w moich osobistych zadaniach.
- PurifyPlus: Brak wsparcia dla środowisk Win-x64, przede wszystkim Windows 7. Poza tym doskonała. Wielu moich kolegów z innych działów przysięga na to.
- VS2008 Profiler: Produkuje dane wyjściowe w zakresie 100 + gigów w trybie śledzenia funkcji przy wymaganej rozdzielczości. Z drugiej strony daje solidne wyniki.
- GProf: Wymaga nawet umiarkowanie skutecznego GCC.
- VTune: wsparcie W7 VTune graniczy z przestępczością. Poza tym doskonale
- PIN: musiałbym zhakować własne narzędzie, więc jest to ostateczność.
- Sleepy \ VerySleepy: Przydatne w przypadku mniejszych aplikacji, ale mnie tu zawodzi.
- EasyProfiler: Nieźle, jeśli nie przeszkadza ci trochę ręcznie wprowadzony kod wskazujący, gdzie instrumentować.
- Valgrind: * tylko nix, ale bardzo dobrze, gdy jesteś w takim środowisku.
- OProfile: tylko Linux.
- Proffy: Strzelają do dzikich koni.
Sugerowane narzędzia, których nie wypróbowałem:
- XPerf:
- Glowcode:
- Devpartner:
Uwagi: Środowisko Intel w tej chwili. VS2008, zwiększ biblioteki. Qt 4+. I nędzny humdinger z nich wszystkich: integracja Qt / MFC za pośrednictwem trolltech.
Teraz: prawie dwa tygodnie później wygląda na to, że mój problem został rozwiązany. Dzięki różnorodnym narzędziom, w tym prawie wszystkim na liście i kilku moim osobistym sztuczkom, znaleźliśmy główne wąskie gardła. Jednak zamierzam nadal testować, odkrywać i wypróbowywać nowe profile, a także nowe technologie. Czemu? Ponieważ jestem wam to winien, bo rządzicie. Trochę spowalnia to oś czasu, ale nadal jestem bardzo podekscytowany możliwością dalszego wypróbowywania nowych narzędzi.
Opis
Wśród wielu innych problemów, ostatnio przełączono szereg komponentów na niewłaściwy model wątków, co spowodowało poważne zawieszanie się, ponieważ kod pod nami nagle przestał być wielowątkowy. Nie mogę powiedzieć więcej, ponieważ narusza to moją umowę o zachowaniu poufności, ale mogę powiedzieć, że nigdy nie zostałoby to znalezione podczas zwykłej inspekcji ani nawet podczas normalnego przeglądu kodu. Bez profilerów, kaligrafów i przypadkowych pauz w połączeniu nadal wykrzykiwalibyśmy naszą furię na piękny niebieski łuk nieba. Na szczęście pracuję z jednymi z najlepszych hakerów, jakich kiedykolwiek spotkałem, i mam dostęp do niesamowitego wersetu pełnego świetnych narzędzi i wspaniałych ludzi.
Gentleholk, ogromnie to doceniam i żałuję tylko, że nie mam wystarczającej liczby reputacji, aby wynagrodzić każdego z was nagrodą. Nadal uważam, że jest to ważne pytanie, aby uzyskać lepszą odpowiedź niż te, które otrzymaliśmy do tej pory w SO.
W rezultacie co tydzień przez następne trzy tygodnie będę wnosił największą nagrodę, na jaką mnie stać, i nagradzać ją najmilszym narzędziem, o którym myślę, że nie jest powszechnie znana. Miejmy nadzieję, że po trzech tygodniach uzyskamy ostateczny profil osób zajmujących się profilowaniem, jeśli wybaczycie mi moją karę.
Na wynos
Użyj profilera. Są wystarczająco dobre dla Ritchiego, Kernighana, Bentleya i Knutha. Nie obchodzi mnie, kim myślisz, że jesteś. Użyj profilera. Jeśli ten, który masz, nie działa, znajdź inny. Jeśli nie możesz go znaleźć, wpisz jeden. Jeśli nie możesz go zakodować, jest to małe rozłączenie lub po prostu utknąłeś, użyj losowej pauzy. Jeśli wszystko inne zawiedzie, zatrudnij kilku absolwentów, aby wybili profilera.
Dłuższy widok
Pomyślałem więc, że fajnie byłoby napisać trochę retrospektywy. Zdecydowałem się na intensywną współpracę z Parallel Studios, po części dlatego, że w rzeczywistości jest ono oparte na narzędziu PIN. Mając kontakty naukowe z niektórymi zaangażowanymi badaczami, czułem, że jest to prawdopodobnie znak jakiejś jakości. Na szczęście miałem rację. Chociaż GUI jest trochę okropne, okazało się, że IPS jest niesamowicie przydatny, chociaż nie mogę go wygodnie polecić wszystkim. Krytycznie, nie ma oczywistego sposobu, aby uzyskać liczbę trafień na poziomie linii, coś, co zapewnia AQT i wiele innych profilerów, i stwierdziłem, że jest bardzo przydatny do badania między innymi współczynnika wyboru gałęzi. W sieci również podobało mi się używanie AQTime i zauważyłem, że ich wsparcie jest naprawdę responsywne. Ponownie muszę zakwalifikować moją rekomendację: Wiele ich funkcji nie działa tak dobrze, a niektóre z nich są wręcz podatne na awarie w systemie Win7x64. XPerf również działał znakomicie, ale jest boleśnie powolny, jeśli chodzi o szczegóły próbkowania wymagane do uzyskania dobrych odczytów w niektórych rodzajach aplikacji.
W tej chwili muszę powiedzieć, że nie sądzę, aby istniała ostateczna opcja profilowania kodu C ++ w środowisku W7x64, ale z pewnością istnieją opcje, które po prostu nie wykonują żadnej użytecznej usługi.
Odpowiedzi:
Pierwszy:
Profile próbkowania czasu są bardziej niezawodne niż profilery próbkowania procesora. Nie znam narzędzi programistycznych systemu Windows, więc nie mogę powiedzieć, które z nich są które. Większość programów profilujących pobiera próbki procesora.
Profiler próbkowania procesora pobiera ślad stosu co N instrukcji.
Ta technika ujawni części kodu, które są powiązane z procesorem. Co jest niesamowite, jeśli jest to szyjka butelki w twojej aplikacji. Niezbyt dobrze, jeśli wątki aplikacji spędzają większość czasu na walce o muteks.
Profiler próbkowania czasu pobiera ślad stosu co N mikrosekund.
Ta technika skupia się na „wolnym” kodzie. Czy przyczyna jest związana z procesorem CPU, blokowaniem powiązanym we / wy, powiązanym z muteksem lub sekcjami kodu powodującymi trakcję pamięci podręcznej. Krótko mówiąc, każdy fragment kodu spowalniający Twoją aplikację będzie się wyróżniał.
Więc jeśli to możliwe, użyj profilera próbkowania czasu, szczególnie podczas profilowania kodu wątkowego.
Druga:
Profile do próbkowania generują porcje danych. Dane są niezwykle przydatne, ale często jest ich zbyt wiele, aby można je było łatwo wykorzystać. Wizualizator danych profilu bardzo tutaj pomaga. Najlepszym narzędziem do wizualizacji danych profilu, jakie znalazłem, jest gprof2dot . Nie daj się zwieść nazwie, obsługuje ona wszystkie rodzaje danych wyjściowych profilera próbkowania (AQtime, Sleepy, XPerf itp.). Gdy wizualizacja wskaże nieprawidłową funkcję (-e), wróć do nieprzetworzonych danych profilu, aby uzyskać lepsze wskazówki na temat prawdziwej przyczyny.
Narzędzie gprof2dot generuje opis wykresu kropkowego , który następnie podajesz do narzędzia graphviz . Dane wyjściowe to w zasadzie wykres wywoławczy z funkcjami oznaczonymi kolorami zgodnie z ich wpływem na aplikację.
Kilka wskazówek, jak sprawić, by gprof2dot generował ładne wyjście.
--skew
Na moich wykresach używam 0,001, dzięki czemu mogę łatwo zobaczyć gorące ścieżki kodu. W przeciwnym razieint main()
dominuje na wykresie.--strip
. Jest to szczególnie prawdziwe w przypadku Boost.malloc
to niszczenie stosu i pochłanianie 15%.źródło
Co się stało, gdy spróbowałeś przypadkowego wstrzymania? Używam go cały czas w potwornej aplikacji. Powiedziałeś, że to za mało informacji i zasugerowałeś, że potrzebujesz wysokiej rozdzielczości. Czasami ludzie potrzebują trochę pomocy w zrozumieniu, jak z niego korzystać.
To, co robię w VS, to konfigurowanie wyświetlania stosu, tak aby nie pokazywał mi argumentów funkcji, ponieważ powoduje to, że wyświetlanie stosu jest całkowicie nieczytelne, IMO.
Następnie pobieram około 10 próbek, naciskając przycisk „pauza” w czasie, gdy muszę czekać . Używam ^ A, ^ C i ^ V, aby skopiować je do notatnika w celach informacyjnych. Następnie badam każdy z nich, aby dowiedzieć się, co w tym czasie próbowałem osiągnąć.
Jeśli próbował wykonać coś na 2 lub więcej próbkach, a to nie jest absolutnie konieczne, to znalazłem problem na żywo i wiem z grubsza, ile zaoszczędzi to naprawienie.
Są rzeczy, których tak naprawdę nie musisz wiedzieć, na przykład dokładne wartości procentowe nie są ważne, a to, co dzieje się w kodzie strony trzeciej, nie jest ważne, ponieważ nie możesz nic z tym zrobić . To, z czym możesz coś zrobić, to bogaty zestaw punktów wywoławczych w kodzie, które możesz modyfikować, wyświetlanych na każdym przykładzie stosu. To twoje szczęśliwe łowisko.
Przykłady rodzajów rzeczy, które znajduję:
Podczas uruchamiania może mieć głębokość około 30 warstw, podczas próby wyodrębnienia umiędzynarodowionych ciągów znaków z zasobów DLL. Jeśli sprawdzane są rzeczywiste ciągi, łatwo może się okazać, że nie muszą one być umiędzynarodowione, tak jak są to ciągi, których użytkownik nigdy nie widzi.
Podczas normalnego użytkowania jakiś kod niewinnie ustawia właściwość Modified w jakimś obiekcie. Ten obiekt pochodzi z superklasy, która przechwytuje zmianę i wyzwala powiadomienia, które pojawiają się w całej strukturze danych, manipulując interfejsem użytkownika, tworząc i niszcząc przeszkody w trudny do przewidzenia sposób. To może się bardzo zdarzyć - nieoczekiwane konsekwencje powiadomień.
Wypełnianie arkusza wiersz po wierszu, komórka po komórce. Okazuje się, że jeśli zbudujesz wiersz od razu, z tablicy wartości, będzie to znacznie szybsze.
PS Jeśli korzystasz z wielu wątków, po wstrzymaniu wszystkich wątków zatrzymują się. Przyjrzyj się stosowi wywołań każdego wątku. Są szanse, że tylko jeden z nich jest prawdziwym winowajcą, a inni są na biegu jałowym.
źródło
Odniosłem pewien sukces z AMD CodeAnalyst .
źródło
Czy masz funkcję MFC OnIdle? W przeszłości miałem aplikację działającą prawie w czasie rzeczywistym, którą musiałem naprawić, która odrzucała pakiety szeregowe po ustawieniu prędkości na 19,2K, z którą PentiumD powinien być w stanie nadążyć. Funkcja OnIdle była tym, co zabijało rzeczy. Nie jestem pewien, czy QT ma taką koncepcję, ale też bym to sprawdził.
źródło
A co z VS Profiler - jeśli generuje tak duże pliki, być może interwał próbkowania jest zbyt częsty? Spróbuj go obniżyć, ponieważ prawdopodobnie i tak masz wystarczająco dużo próbek.
I idealnie, upewnij się, że nie pobierasz próbek, dopóki faktycznie nie ćwiczysz obszaru problemu. Więc zacznij od wstrzymania zbierania danych, poproś program, aby wykonał swoją „powolną czynność”, a następnie rozpocznij zbieranie. Potrzebujesz tylko 20 sekund zbierania. Zatrzymaj zbieranie po tym.
Powinno to pomóc zmniejszyć rozmiary plików próbki i uchwycić tylko to, co jest niezbędne do analizy.
źródło
Z powodzeniem korzystałem z PurifyPlus dla Windows. Chociaż nie jest tania, IBM dostarcza wersję próbną, która jest nieco okaleczona. Wszystko, czego potrzebujesz do profilowania za pomocą quantify, to pliki pdb i linkowanie z / FIXED: NO. Jedyna wada: brak wsparcia dla Win7 / 64.
źródło
Easyprofiler - nie widziałem tego jeszcze tutaj, więc nie jestem pewien, czy już go oglądałeś. Sposób zbierania danych metrycznych jest nieco inny. Wadą korzystania z podejścia do profilu czasu kompilacji jest to, że musisz wprowadzić zmiany w bazie kodu. Dlatego musisz mieć pojęcie o tym, gdzie może być wolne, i wstawić tam kod profilowania.
Przechodzenie przez swoich najnowszych komentarzy choć brzmi to jak jesteś przynajmniej co jakiś postęp. Być może to narzędzie dostarczy Ci przydatnych danych. Jeśli nic więcej, ma kilka naprawdę czystych wykresów i zdjęć: P
źródło
Jeszcze dwie propozycje narzędzi.
Luke Stackwalker ma urocze imię (nawet jeśli trochę się stara jak na mój gust), nic cię to nie kosztuje, a otrzymasz kod źródłowy. Twierdzi również, że obsługuje programy wielowątkowe. Więc na pewno warto się zakręcić.
http://lukestackwalker.sourceforge.net/
Również Glowcode, który wskazałem mi jako warty użycia:
http://www.glowcode.com/
Niestety od jakiegoś czasu nie wykonałem żadnej pracy na komputerze, więc nie próbowałem żadnego z nich. Mam nadzieję, że sugestie i tak okażą się pomocne.
źródło
Checkout XPerf
Jest to darmowy, nieinwazyjny i rozszerzalny profiler oferowany przez MS. Został opracowany przez firmę Microsoft w celu profilowania systemu Windows.
źródło
Jeśli podejrzewasz pętlę zdarzeń, czy możesz zastąpić QCoreApplication :: notify () i dosome ręczne profilowanie (jedna lub dwie mapy nadawców / zdarzeń na liczniki / czas)?
Myślę, że najpierw rejestrujesz częstotliwość typów zdarzeń, a następnie dokładniej badasz te zdarzenia (który obiekt go wysyła, co zawiera itp.). Sygnały między wątkami są niejawnie umieszczane w kolejce, więc trafiają do pętli zdarzeń (a także oczywiście jawnych połączeń w kolejce).
Zrobiliśmy to, aby przechwytywać i zgłaszać wyjątki w naszych programach obsługi zdarzeń, więc tak naprawdę każde zdarzenie tam przechodzi.
Tylko pomysł.
źródło
QObject* object
parametr. Może MetaCall jest typem dla wszystkich sygnałów (wydaje się prawdopodobne), ale nie jestem pewien. To wykracza nieco poza moje doświadczenie, ale zajrzenie do źródła Qt może przynieść trochę prawdy. (Lub zadaj bardziej konkretne pytanie, wpisując wywołania sygnałów w kolejce tutaj w SO .. :)Edycja: Widzę, że wspomniałeś o tym w swoim pierwszym poście. Cholera, nigdy nie myślałem, że będę tym facetem.
Możesz użyć Pin, aby instrumentować swój kod z większą szczegółowością. Myślę, że Pin pozwoliłby ci stworzyć narzędzie do liczenia, ile razy wchodzisz w funkcję lub ile znaczników zegara tam spędzasz, z grubsza emulując coś takiego jak VTune lub CodeAnalyst. Następnie możesz odrzucić, które funkcje są oprzyrządowane, aż problemy z synchronizacją znikną.
źródło
Mogę powiedzieć, czego używam na co dzień.
a) Analityk AMD Code
b) VTune.
Jest bardzo dobrze zintegrowany z vs2008
po zapoznaniu się z hotspotami musisz próbkować nie tylko czas, ale także inne rzeczy, takie jak pominięcia pamięci podręcznej i zużycie pamięci. To jest bardzo ważne . Skonfiguruj sesję próbkowania i edytuj właściwości. Zawsze próbuję pod kątem czasu, odczytu / zapisu pamięci i błędów pamięci podręcznej (trzy różne przebiegi)
Ale nie tylko to narzędzie, ale także doświadczenie w profilowaniu. A to oznacza zrozumienie, jak działa procesor / pamięć / PCI ... więc to moja trzecia opcja
c) Testowanie jednostkowe
Jest to bardzo ważne, jeśli tworzysz dużą aplikację, która wymaga dużej wydajności. Jeśli nie możesz podzielić aplikacji na kilka części, śledzenie użycia procesora będzie trudne. Nie testuję wszystkich przypadków i klas, ale mam zakodowane wykonania i pliki wejściowe z ważnymi funkcjami.
Moja rada jest taka, aby użyć losowego próbkowania w kilku małych testach i spróbować ujednolicić strategię profilu.
źródło
Używam Xperf / ETW do wszystkich moich potrzeb związanych z profilowaniem. Ma stromą krzywą uczenia się, ale jest niesamowicie potężny. Jeśli profilujesz w systemie Windows, musisz znać xperf. Często używam tego profilera, aby znaleźć problemy z wydajnością w moim kodzie i kodzie innych osób.
W konfiguracji, w której go używam:
To dużo danych na jednej osi czasu dla wszystkich procesów. Żaden inny program profilujący w systemie Windows nie może tego zrobić.
Dużo pisałem na blogu o tym, jak używać xperf / ETW. Te posty na blogu i kilka profesjonalnych filmów szkoleniowych można znaleźć tutaj: http://randomascii.wordpress.com/2014/08/19/etw-training-videos-available-now/
Jeśli chcesz dowiedzieć się, co może się stać, jeśli nie używasz xperfa, przeczytaj te posty na blogu: http://randomascii.wordpress.com/category/investigative-reporting/ To są opowieści o problemach z wydajnością, które znalazłem w kodzie innych osób , to powinno zostać znalezione przez programistów. Obejmuje to ładowanie pliku mshtml.dll do kompilatora VC ++, odmowę usługi w plikach wyszukiwania VC ++, ograniczanie termiczne na zaskakującej liczbie maszyn klientów, powolne, jednoetapowe uruchamianie w programie Visual Studio, alokację 4 GB w sterownik dysku, błąd wydajności programu PowerPoint i nie tylko.
źródło
Właśnie skończyłem pierwszą użyteczną wersję CxxProf , przenośnej, ręcznej, instrumentowanej biblioteki profilowania dla C ++.
Spełnia następujące cele:
Te punkty zostały wyrwane z wiki projektu , zajrzyj tam, aby uzyskać więcej informacji.
Zastrzeżenie: Jestem głównym twórcą CxxProf
źródło
Po prostu wyrzuć to, nawet jeśli nie jest to pełnowymiarowy profiler: jeśli wszystko, czego szukasz, to zawieszone pętle zdarzeń, które wymagają długiego przetwarzania zdarzenia, narzędzie ad-hoc jest prostą sprawą w Qt. Podejście to można łatwo rozszerzyć, aby śledzić, jak długo trwało przetwarzanie każdego zdarzenia i jakie to były zdarzenia, i tak dalej. Nie jest to uniwersalny profiler, ale oparty na pętli zdarzeń.
W Qt wszystkie międzywątkowe wywołania szczelin sygnałowych są dostarczane za pośrednictwem pętli zdarzeń, podobnie jak zegary, powiadomienia o sieci i portach szeregowych oraz wszystkie interakcje użytkownika. Dlatego obserwacja pętli zdarzeń jest dużym krokiem w kierunku zrozumienia, gdzie aplikacja spędza swój czas.
źródło
DevPartner, pierwotnie opracowany przez NuMega, a obecnie dystrybuowany przez MicroFocus, był kiedyś rozwiązaniem wybieranym do profilowania i analizy kodu (na przykład wycieki pamięci i zasobów). Nie próbowałem tego ostatnio, więc nie mogę zapewnić, że to pomoże; ale kiedyś miałem z nim doskonałe wyniki, więc jest to alternatywa, którą rozważam, aby ponownie zainstalować w naszym procesie jakości kodu (zapewniają 14-dniową wersję próbną)
źródło
chociaż twój system operacyjny to win7, program nie może działać pod xp? co powiesz na profilowanie go pod xp, a wynik powinien być wskazówką dla win7.
źródło
Jest tutaj wymienionych wiele profilerów, a kilka z nich wypróbowałem - jednak ostatecznie napisałem własne na podstawie tego:
http://code.google.com/p/high-performance-cplusplus-profiler/
Oczywiście wymaga to zmodyfikowania bazy kodu, ale jest idealny do zawężania wąskich gardeł, powinien działać na wszystkich x86 (może to być problem z wielordzeniowymi komputerami, ale używa rdtsc - i tak jest to tylko dla orientacyjnego czasu) - więc uważam, że jest to wystarczające dla moich potrzeb ..)
źródło
Używam profilera Orbit, łatwego, otwartego i potężnego! https://orbitprofiler.com/
źródło