Alternatywy dla gprof [zamknięte]


166

Jakie inne programy robią to samo co gprof?


2
jakie platformy Cię interesują?
osgx

2
Interesuje mnie Linux.
neuromancer


13
@Gregory - Jestem skłonny się zgodzić i może powinien przyczynić się własnymi odpowiedziami, 229 vs 6, wszystkie 6 odpowiedzi dotyczą jego własnych pytań ...
Jean-Bernard Pellerin

5
Jak to pytanie może nie być konstruktywne?
JohnTortugo

Odpowiedzi:


73

Valgrind ma profiler zliczania instrukcji z bardzo ładnym wizualizatorem o nazwie KCacheGrind . Jak radzi Mike Dunlavey, Valgrind liczy ułamek instrukcji, dla których procedura jest aktywna na stosie, chociaż przykro mi to mówić, wydaje się być zdezorientowana w obecności wzajemnej rekursji. Ale wizualizator jest bardzo ładny i wyprzedza go o lata świetlne gprof.


2
@Norman: ++ To zamieszanie związane z rekurencją wydaje się być typowe dla systemów, które mają koncepcję propagacji czasów między węzłami na grafie. Myślę też, że czas zegara ściennego jest ogólnie bardziej przydatny niż czasy instrukcji procesora, a linie kodu (instrukcje wywołania) są bardziej przydatne niż procedury. Jeśli pobierane są próbki stosu w losowych czasach zegara ściennego, wówczas ułamkowy koszt linii (lub procedury lub innego opisu, który możesz wykonać) jest po prostu szacowany na podstawie ułamka próbek, które go wykazują.
Mike Dunlavey,

1
... Podkreślam instrukcje połączeń, ale dotyczy to wszelkich instrukcji. Jeśli ktoś ma wąskie gardło punktu dostępu uczciwego do dobroci, takie jak bąbelkowy rodzaj dużej tablicy liczb, wówczas instrukcje porównania / skoku / zamiany / inkrementacji pętli wewnętrznej będą na górze / na dole prawie każdej próbki stosu . Ale (zwłaszcza, że ​​oprogramowanie staje się duże i prawie żadna procedura nie ma zbyt wiele czasu dla siebie), wiele problemów to w rzeczywistości instrukcje telefoniczne, wymagające pracy, która, gdy jest jasne, ile kosztuje, tak naprawdę nie musi być wykonana.
Mike Dunlavey

3
... Sprawdź to. Myślę, że są prawie na dobrej drodze: rotateright.com/zoom.html
Mike Dunlavey,

195

gprof (przeczytaj artykuł) istnieje ze względów historycznych. Jeśli uważasz, że pomoże Ci to znaleźć problemy z wydajnością, nigdy nie był reklamowany jako taki. Oto, co mówi artykuł:

Profil można wykorzystać do porównania i oceny kosztów różnych wdrożeń.

Nie mówi, że można go użyć do zidentyfikowania różnych wdrożeń do oceny, chociaż sugeruje , że w szczególnych okolicznościach może:

zwłaszcza jeśli okaże się, że małe fragmenty programu dominują w czasie wykonywania.

A co z problemami, które nie są tak zlokalizowane? Czy to nie ma znaczenia? Nie stawiaj na gprof oczekiwań , które nigdy nie zostały zgłoszone. To tylko narzędzie pomiarowe i tylko operacje związane z procesorem.

Spróbuj tego zamiast tego.
Oto przykład 44-krotnego przyspieszenia.
Oto przyspieszenie 730x.
Oto 8-minutowa demonstracja wideo.
Oto wyjaśnienie statystyk.
Oto odpowiedź na krytykę.

Jest prosta obserwacja dotycząca programów. W danej realizacji każda instrukcja odpowiada za jakiś ułamek całkowitego czasu (zwłaszczacall instrukcje), w tym sensie, że gdyby jej nie było, czas nie zostałby wykorzystany. W tym czasie instrukcja znajduje się na stosie **. Kiedy to zrozumiesz, zobaczysz, że -

gprof uosabia pewne mity dotyczące wydajności, takie jak:

  1. że próbkowanie licznika programu jest przydatne.
    Jest to przydatne tylko wtedy, gdy masz niepotrzebne wąskie gardło punktu aktywnego, takie jak bąbelkowy rodzaj dużej tablicy wartości skalarnych. Gdy na przykład zmienisz to na sortowanie za pomocą porównywania ciągów, nadal jest to wąskie gardło, ale próbkowanie licznika programowego tego nie zauważy, ponieważ teraz punkt aktywny jest w porównywaniu ciągów. Z drugiej strony, gdyby miał próbkować rozszerzony plik licznik programu (stos wywołań), punkt, w którym wywoływana jest funkcja porównywania łańcuchów, pętla sortowania, jest wyraźnie wyświetlany. W rzeczywistości gprof był próbą zaradzenia ograniczeniom próbkowania tylko dla komputerów PC.

  2. że funkcje czasowe są ważniejsze niż przechwytywanie czasochłonnych wierszy kodu.
    Powodem tego mitu jest to, że gprof nie był w stanie przechwycić próbek stosu, więc zamiast funkcje, liczy ich wywołania i próbuje przechwycić wykres wywołań. Jednak po zidentyfikowaniu kosztownej funkcji nadal musisz szukać w niej wierszy odpowiedzialnych za czas. Gdyby były próbki w stosie, których nie musiałbyś szukać, te linie byłyby na próbkach. (Typowa funkcja może mieć od 100 do 1000 instrukcji. Wywołanie funkcji to 1 instrukcja, więc coś, co lokalizuje kosztowne wywołania, jest o 2-3 rzędy wielkości dokładniejsze).

  3. że wykres wywołań jest ważny.
    To, co musisz wiedzieć o programie, to nie to, gdzie spędza swój czas, ale dlaczego. Kiedy spędza czas w funkcji, każda linia kodu na stosie daje jedno ogniwo w łańcuchu rozumowania, dlaczego tam się znajduje. Jeśli widzisz tylko część stosu, możesz zobaczyć tylko część powodu, więc nie możesz stwierdzić na pewno, czy ten czas jest rzeczywiście potrzebny. Co mówi wykres połączeń? Każdy łuk mówi ci, że jakaś funkcja A była w trakcie wywoływania jakiejś funkcji B przez pewien ułamek czasu. Nawet jeśli A ma tylko jedną taką linię kodu wywołującą B, ta linia podaje tylko niewielką część przyczyny. Jeśli masz szczęście, może ta linia ma kiepski powód. Zwykle musisz zobaczyć wiele jednoczesnych linii, aby znaleźć zły powód, jeśli taki istnieje. Jeśli A dzwoni do B w więcej niż jednym miejscu, powie Ci jeszcze mniej.

  4. że rekurencja jest trudnym i mylącym problemem. Dzieje się
    tak tylko dlatego, że gprof i inni profilery dostrzegają potrzebę wygenerowania wykresu wywołań, a następnie przypisania czasów do węzłów. Jeśli ktoś ma próbki stosu, koszt czasu każdego wiersza kodu, który pojawia się na próbkach, jest bardzo prostą liczbą - ułamkiem próbek, na których się znajduje. Jeśli występuje rekursja, to dana linia może pojawić się więcej niż raz na próbce. Bez znaczenia. Załóżmy, że próbki są pobierane co N ms, a linia pojawia się na F% z nich (pojedynczo lub nie). Jeśli można sprawić, że ta linia nie zajmie czasu (na przykład przez usunięcie jej lub rozgałęzienie wokół niej), wtedy te próbki znikną , a czas zostanie skrócony o F%.

  5. że dokładność pomiaru czasu (a tym samym duża liczba próbek) jest ważna.
    Pomyśl o tym przez chwilę. Jeśli wiersz kodu zawiera 3 próbki na pięć, to gdybyś mógł go wystrzelić jak żarówkę, jest to około 60% mniej czasu, który zostałby wykorzystany. Teraz wiesz, że gdybyś pobrał różne 5 próbek, mógłbyś zobaczyć to tylko 2 razy lub aż 4. Tak więc pomiar 60% bardziej przypomina ogólny zakres od 40% do 80%. Gdyby to było tylko 40%, czy powiedziałbyś, że problemu nie warto naprawiać? Jaki jest więc punkt dokładności czasowej, kiedy naprawdę chcesz znaleźć problemy ? 500 lub 5000 próbek zmierzyłoby problem z większą precyzją, ale nie wykryłoby go dokładniej.

  6. że liczenie wywołań instrukcji lub funkcji jest przydatne.
    Załóżmy, że wiesz, że funkcja została wywołana 1000 razy. Czy możesz z tego stwierdzić, ile czasu to kosztuje? Musisz także wiedzieć, jak długo trwa średnio, pomnożyć to przez liczbę i podzielić przez całkowity czas. Średni czas wywołania może wahać się od nanosekund do sekund, więc sam licznik niewiele mówi. Jeśli są próbki w stosie, koszt procedury lub dowolnego oświadczenia to tylko ułamek próbek, w których się znajdują. Ten ułamek czasu w zasadzie można by ogólnie zaoszczędzić, gdyby rutyna lub stwierdzenie nie zajmowało czasu, więc to właśnie ma najbardziej bezpośredni związek z wynikami.

  7. że próbki nie muszą być pobierane, gdy są zablokowane
    . Przyczyny tego mitu są dwojakie: 1) próbkowanie z komputera jest bez znaczenia, gdy program czeka, oraz 2) zainteresowanie dokładnością synchronizacji. Jednak w przypadku (1) program może bardzo dobrze czekać na coś, o co prosił, na przykład we / wy pliku, o czym musisz wiedzieć i które próbki stosu ujawniają. (Oczywiście chcesz wykluczyć próbki podczas oczekiwania na dane wejściowe użytkownika). W przypadku (2), jeśli program czeka po prostu z powodu konkurencji z innymi procesami, prawdopodobnie dzieje się to w dość przypadkowy sposób podczas jego działania. Więc chociaż program może zająć więcej czasu, nie będzie to miało dużego wpływu na statystyki, które mają znaczenie, procent czasu, przez jaki instrukcje znajdują się na stosie.

  8. że "czas własny" ma znaczenie
    Czas jaźni ma sens tylko wtedy, gdy mierzysz na poziomie funkcji, a nie na poziomie liniowym i myślisz, że potrzebujesz pomocy w rozeznaniu, czy czas funkcji przechodzi do czysto lokalnych obliczeń, czy też w wywołanych procedurach. W przypadku podsumowania na poziomie liniowym linia reprezentuje czas własny, jeśli znajduje się na końcu stosu, w przeciwnym razie reprezentuje czas włącznie. Tak czy inaczej, to, co kosztuje, to procent próbek stosu, na którym się znajduje, więc w każdym przypadku lokalizuje go dla Ciebie.

  9. że próbki muszą być pobierane z dużą częstotliwością
    Wynika to z pomysłu, że problem z wydajnością może występować szybko i że próbki muszą być częste, aby go uderzyć. Ale jeśli problem kosztuje, powiedzmy 20% z całkowitego czasu działania wynoszącego 10 sekund (lub cokolwiek), to każda próbka w tym łącznym czasie będzie miała 20% szansy na trafienie, bez względu na to, czy problem wystąpi w jednym kawałku, takim jak ten
    .....XXXXXXXX...........................
    .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 próbek, 4 trafienia)
    lub w wielu małych kawałkach takich jak ten
    X...X...X.X..X.........X.....X....X.....
    .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 próbek, 3 trafienia)
    Tak czy inaczej, liczba trafień wyniesie średnio około 1 do 5, niezależnie od tego, ile próbek zostanie pobranych, lub jak mało. (Średnia = 20 * 0,2 = 4. Odchylenie standardowe = +/- sqrt (20 * 0,2 * 0,8) = 1,8.)

  10. które próbują odnaleźć się wąskim gardłem
    , jakby było tylko jedno. Rozważ następujący harmonogram wykonania: vxvWvzvWvxvWvYvWvxvWv.vWvxvWvYvW
    Składa się z naprawdę użytecznej pracy, reprezentowanej przez .. Występują problemy vWxYzz wydajnością zajmujące odpowiednio 1/2, 1/4, 1/8, 1/16, 1/32 czasu. Pobieranie próbek jest vłatwe. Jest usuwany, pozostawiając
    xWzWxWYWxW.WxWYW
    Teraz program trwa o połowę krócej, teraz Wzajmuje połowę czasu i można go łatwo znaleźć. Jest usuwany, pozostawiając
    xzxYx.xY
    Ten proces jest kontynuowany, za każdym razem usuwając procentowo największy problem z wydajnością, aż nie można znaleźć niczego do usunięcia. Teraz jedyną wykonywaną rzeczą jest .wykonanie przez 1/32 czasu używanego przez oryginalny program. To jest efekt powiększenia, przez co usunięcie problemu powoduje zwiększenie pozostałej części o procent, ponieważ zmniejsza się mianownik.
    Kolejną istotną kwestią jest to, że każdy problem musi zostać znaleziony - nie pomijając żadnego z 5. Każdy problem, który nie został znaleziony i naprawiony, poważnie zmniejsza ostateczny współczynnik przyspieszenia. Samo znalezienie niektórych, ale nie wszystkich, nie jest „wystarczająco dobre”.

DODANE: Chciałbym tylko wskazać jeden powód, dla którego gprof jest popularny - jest nauczany, prawdopodobnie dlatego, że jest darmowy, łatwy do nauczenia i istnieje od dawna. Szybkie wyszukiwanie w Google pozwala zlokalizować niektóre instytucje akademickie, które tego nauczają (lub wydają się):

berkeley bu clemson colorado duke Earlham fsu indiana mit msu ncsa.illinois ncsu nyu ou princeton psu stanford ucsd umd umich utah utexas utk wustl

** Z wyjątkiem innych sposobów zgłaszania prośby o wykonanie pracy, które nie pozostawiają śladu wyjaśniającego dlaczego , na przykład wysyłanie wiadomości.


3
@Norman: Zrobiłem na tej podstawie profiler w C dla DOS, około 93 roku. Nazwałem go jeszcze jednym analizatorem wydajności i prezentowałem go na spotkaniach IEEE, ale to wszystko. Istnieje produkt firmy RotateRight o nazwie Zoom, który nie jest zbyt odległy. Na * nix pstack jest dobry do robienia tego ręcznie. Moja lista rzeczy do zrobienia (farmakometria w systemie Windows) ma około mili, co wyklucza zabawne projekty, nie wspominając o rodzinie. To może być przydatne: stackoverflow.com/questions/1777669/ ...
Mike Dunlavey,

6
Zawsze uważałem, że profilery nie są zbyt przydatne do naprawiania powolnego kodu i zamiast tego używam selektywnych fragmentów kodu debugującego do pomiaru czasu potrzebnego na grupę wybranych przeze mnie instrukcji, często wspomaganych przez jakieś trywialne małe makra lub cokolwiek innego. Nigdy nie zajmowało mi zbyt dużo czasu, aby znaleźć winnego, ale zawsze wstydziłem się, że moje „niedźwiedzie skóry i kamienne noże” podchodzą, gdy „wszyscy” (o ile wiem) używają wymyślnych narzędzi. Dziękuję za pokazanie mi, dlaczego nigdy nie mogłem uzyskać potrzebnych informacji od profilera. To jeden z najważniejszych pomysłów, jakie widziałem w SO. Dobra robota!
Wayne Conrad,

7
@osgx: Nie chcę niczego zgrywać. To jak stary ulubiony samochód, prosty i wytrzymały, ale są rzeczy, których nie robi, i musimy być tego świadomi, i nie tylko, musimy obudzić się z mitów. Doceniam, że na niektórych platformach pobranie próbek stosu może być trudne, ale jeśli problem jest taki, że gprof go nie znajdzie, to fakt, że jest to jedyne narzędzie, to niewielki komfort.
Mike Dunlavey

2
@Andrew: ... i jeśli ten powód dotyczy jakiejś znaczącej części próbek (na przykład więcej niż 1), to w tych próbkach znajdują się wiersze kodu, które mogłyby wyeliminować tę aktywność. Wykres może dać ci wskazówkę , ale niezbyt duża liczba próbek stosu po prostu ci je pokaże.
Mike Dunlavey

2
@Matt: Przykłady problemów z wydajnością we / wy znalezionych w ten sposób: 1) drukowanie komunikatów dziennika do pliku lub konsoli, które błędnie uznano za nieistotne. 2) Konwersja między tekstem a podwojeniem liczbowych operacji we / wy. 3) Subterranean IO wyodrębnia umiędzynarodowione ciągi podczas uruchamiania, łańcuchy, które, jak się okazuje, nie muszą być umiędzynarodowione. Trafiłem na wiele takich przykładów.
Mike Dunlavey,

63

Ponieważ nic tu nie widziałem perf co jest stosunkowo nowym narzędziem do profilowania jądra i aplikacji użytkownika w systemie Linux, postanowiłem dodać te informacje.

Po pierwsze - to jest tutorial o profilowaniu Linuksa zperf

Możesz użyć, perfjeśli twoje jądro Linuksa jest większe niż 2.6.32 lub oprofilejeśli jest starsze. Oba programy nie wymagają od ciebie instrumentowania twojego programu (jak gprofwymagania). Jednak aby poprawnie uzyskać wykres wywołań w programie perf, musisz zbudować swój program -fno-omit-frame-pointer. Na przykład:g++ -fno-omit-frame-pointer -O2 main.cpp .

Możesz zobaczyć analizę swojej aplikacji „na żywo” za pomocą perf top:

sudo perf top -p `pidof a.out` -K

Możesz też zarejestrować dane o wydajności uruchomionej aplikacji i przeanalizować je później:

1) Aby zarejestrować dane dotyczące wykonania:

perf record -p `pidof a.out`

lub nagrywać przez 10 sekund:

perf record -p `pidof a.out` sleep 10

lub nagrywać z wykresem wywołań ()

perf record -g -p `pidof a.out` 

2) Analiza zarejestrowanych danych

perf report --stdio
perf report --stdio --sort=dso -g none
perf report --stdio -g none
perf report --stdio -g

Możesz też zarejestrować dane wydajności aplikacji i przeanalizować je po prostu uruchamiając aplikację w ten sposób i czekając na jej zamknięcie:

perf record ./a.out

To jest przykład profilowania programu testowego

Program testowy znajduje się w pliku main.cpp (umieszczę main.cpp na dole wiadomości):

Kompiluję to w ten sposób:

g++ -m64 -fno-omit-frame-pointer -g main.cpp -L.  -ltcmalloc_minimal -o my_test

Używam, libmalloc_minimial.soponieważ jest kompilowany z, -fno-omit-frame-pointerpodczas gdy libc malloc wydaje się być kompilowany bez tej opcji. Następnie uruchamiam program testowy

./my_test 100000000 

Następnie rejestruję dane wydajności uruchomionego procesu:

perf record -g  -p `pidof my_test` -o ./my_test.perf.data sleep 30

Następnie analizuję obciążenie na moduł:

raport perf --stdio -g none --sort comm, dso -i ./my_test.perf.data

# Overhead  Command                 Shared Object
# ........  .......  ............................
#
    70.06%  my_test  my_test
    28.33%  my_test  libtcmalloc_minimal.so.0.1.0
     1.61%  my_test  [kernel.kallsyms]

Następnie analizowane jest obciążenie na funkcję:

raport perf --stdio -g none -i ./my_test.perf.data | c ++ filt

# Overhead  Command                 Shared Object                       Symbol
# ........  .......  ............................  ...........................
#
    29.30%  my_test  my_test                       [.] f2(long)
    29.14%  my_test  my_test                       [.] f1(long)
    15.17%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator new(unsigned long)
    13.16%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator delete(void*)
     9.44%  my_test  my_test                       [.] process_request(long)
     1.01%  my_test  my_test                       [.] operator delete(void*)@plt
     0.97%  my_test  my_test                       [.] operator new(unsigned long)@plt
     0.20%  my_test  my_test                       [.] main
     0.19%  my_test  [kernel.kallsyms]             [k] apic_timer_interrupt
     0.16%  my_test  [kernel.kallsyms]             [k] _spin_lock
     0.13%  my_test  [kernel.kallsyms]             [k] native_write_msr_safe

     and so on ...

Następnie analizowane są łańcuchy połączeń:

raport perf --stdio -g graph -i ./my_test.perf.data | c ++ filt

# Overhead  Command                 Shared Object                       Symbol
# ........  .......  ............................  ...........................
#
    29.30%  my_test  my_test                       [.] f2(long)
            |
            --- f2(long)
               |
                --29.01%-- process_request(long)
                          main
                          __libc_start_main

    29.14%  my_test  my_test                       [.] f1(long)
            |
            --- f1(long)
               |
               |--15.05%-- process_request(long)
               |          main
               |          __libc_start_main
               |
                --13.79%-- f2(long)
                          process_request(long)
                          main
                          __libc_start_main

    15.17%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator new(unsigned long)
            |
            --- operator new(unsigned long)
               |
               |--11.44%-- f1(long)
               |          |
               |          |--5.75%-- process_request(long)
               |          |          main
               |          |          __libc_start_main
               |          |
               |           --5.69%-- f2(long)
               |                     process_request(long)
               |                     main
               |                     __libc_start_main
               |
                --3.01%-- process_request(long)
                          main
                          __libc_start_main

    13.16%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator delete(void*)
            |
            --- operator delete(void*)
               |
               |--9.13%-- f1(long)
               |          |
               |          |--4.63%-- f2(long)
               |          |          process_request(long)
               |          |          main
               |          |          __libc_start_main
               |          |
               |           --4.51%-- process_request(long)
               |                     main
               |                     __libc_start_main
               |
               |--3.05%-- process_request(long)
               |          main
               |          __libc_start_main
               |
                --0.80%-- f2(long)
                          process_request(long)
                          main
                          __libc_start_main

     9.44%  my_test  my_test                       [.] process_request(long)
            |
            --- process_request(long)
               |
                --9.39%-- main
                          __libc_start_main

     1.01%  my_test  my_test                       [.] operator delete(void*)@plt
            |
            --- operator delete(void*)@plt

     0.97%  my_test  my_test                       [.] operator new(unsigned long)@plt
            |
            --- operator new(unsigned long)@plt

     0.20%  my_test  my_test                       [.] main
     0.19%  my_test  [kernel.kallsyms]             [k] apic_timer_interrupt
     0.16%  my_test  [kernel.kallsyms]             [k] _spin_lock
     and so on ...

W tym momencie wiesz, gdzie Twój program spędza czas.

A to jest main.cpp do testu:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

time_t f1(time_t time_value)
{
  for (int j =0; j < 10; ++j) {
    ++time_value;
    if (j%5 == 0) {
      double *p = new double;
      delete p;
    }
  }
  return time_value;
}

time_t f2(time_t time_value)
{
  for (int j =0; j < 40; ++j) {
    ++time_value;
  }
  time_value=f1(time_value);
  return time_value;
}

time_t process_request(time_t time_value)
{

  for (int j =0; j < 10; ++j) {
    int *p = new int;
    delete p;
    for (int m =0; m < 10; ++m) {
      ++time_value;
    }
  }
  for (int i =0; i < 10; ++i) {
    time_value=f1(time_value);
    time_value=f2(time_value);
  }
  return time_value;
}

int main(int argc, char* argv2[])
{
  int number_loops = argc > 1 ? atoi(argv2[1]) : 1;
  time_t time_value = time(0);
  printf("number loops %d\n", number_loops);
  printf("time_value: %d\n", time_value );

  for (int i =0; i < number_loops; ++i) {
    time_value = process_request(time_value);
  }
  printf("time_value: %ld\n", time_value );
  return 0;
}

Właśnie sprawdziłem twój przykład i wykonałem 5 stacków. Oto, co znaleźli: 40% (mniej więcej) czasu f1dzwoniło delete. 40% (mniej więcej) czasu process_requestdzwoniło delete. Znaczną część pozostałej części wydano w new. Pomiary są zgrubne, ale punkty aktywne są precyzyjne.
Mike Dunlavey,

Co to jest stackshot? Czy to jest pstackwyjście?

2
As in my answer, you run it under a debugger and hit ^C at a random time and capture the stack trace. 1) Myślę, że twoja technika nie jest przydatna, gdy musisz analizować problemy z wydajnością programu działającego na serwerze klienta. 2) Nie jestem pewien, jak zastosować tę technikę do uzyskania informacji dla programu mającego wiele wątków, które obsługują różne żądania. Mam na myśli, kiedy ogólny obraz jest dość skomplikowany.

2
Jeśli chodzi o # 1. Czasami klienci dzwonią i mówią, że Twój program działa wolno. Nie możesz od razu tego powiedzieć the problem is outside your code, prawda? Ponieważ możesz potrzebować pewnych informacji, aby poprzeć swój punkt widzenia. W takiej sytuacji w pewnym momencie może być konieczne profilowanie aplikacji. Nie możesz po prostu poprosić klienta o rozpoczęcie gdb i naciśnięcie ^ C i pobranie stosów połączeń. To był mój punkt widzenia. To jest przykład spielwiese.fontein.de/2012/01/22/… . Miałem ten problem i profilowanie bardzo mi pomogło.

2
Jeśli chodzi o # 2. Zgadzam się, że upraszczanie to dobre podejście. Czasami to działa. Jeśli problem z wydajnością występuje tylko na serwerze klienta i nie można ich odtworzyć na serwerze, przydatne są profile.

21

Wypróbuj OProfile . Jest to znacznie lepsze narzędzie do profilowania Twojego kodu. Sugerowałbym również Intel VTune .

Dwa powyższe narzędzia mogą zawęzić czas spędzony w określonej linii kodu, dodać adnotacje do kodu, pokazać asemblację i ile zajmuje konkretna instrukcja. Oprócz metryki czasu można również zapytać o określone liczniki, np. Trafienia w pamięci podręcznej itp.

W przeciwieństwie do gprof, możesz profilować dowolny proces / plik binarny działający w systemie, używając jednego z dwóch.


2
Jak również wspomniano w odpowiedzi Valgrind, Zoom z RotateRight ( rotateright.com ) zapewnia znacznie ładniejszy interfejs i umożliwia zdalne profilowanie.
JanePhanie,

nie lubił profilu, wydawało się to przypadkowe
Matt Joiner

@Matt jakiś konkretny punkt?
Anycorn,

Nie był w stanie poradzić sobie z ponad 10 sekundami wykonywania przed wygenerowaniem przepełnień statystyk, dane wyjściowe nie były szczególnie przydatne, a dokumentacja jest okropna.
Matt Joiner,

1
@Tho OProfile: ARM, POWER, ia64, ...
Anycorn



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.