Alternativen zu gprof [geschlossen]


166

Welche anderen Programme machen dasselbe wie gprof?


2
Für welche Plattformen interessieren Sie sich?
Osgx

2
Ich interessiere mich für Linux.
Neuromancer


13
@ Gregory - Ich bin geneigt zuzustimmen, und vielleicht sollte er mit eigenen Antworten beitragen, 229 vs 6, wobei alle 6 dieser Antworten auf seine eigenen Fragen sind ...
Jean-Bernard Pellerin

5
Wie kann diese Frage nicht konstruktiv sein?
JohnTortugo

Antworten:


73

Valgrind hat einen Befehlszähler-Profiler mit einem sehr schönen Visualisierer namens KCacheGrind . Wie Mike Dunlavey empfiehlt, zählt Valgrind den Bruchteil der Anweisungen, für die eine Prozedur auf dem Stapel ausgeführt wird, obwohl ich leider sagen muss, dass sie bei gegenseitiger Rekursion verwirrt zu sein scheint. Aber der Visualizer ist sehr schön und Lichtjahre voraus gprof.


2
@Norman: ++ Diese Verwirrung über die Rekursion scheint für Systeme endemisch zu sein, die das Konzept haben, Zeiten zwischen Knoten in einem Diagramm zu verlängern. Ich denke auch, dass die Wanduhrzeit im Allgemeinen nützlicher ist als die CPU-Befehlszeiten, und Codezeilen (Aufrufanweisungen) sind nützlicher als Prozeduren. Wenn Stapelproben zu zufälligen Wanduhrzeiten entnommen werden, werden die Teilkosten einer Linie (oder eines Verfahrens oder einer anderen Beschreibung, die Sie vornehmen können) einfach durch den Bruchteil der Proben geschätzt, die sie aufweisen.
Mike Dunlavey

1
... Ich betone Anrufanweisungen, aber sie gelten für alle Anweisungen. Wenn ein Hotspot-Engpass vorliegt, z. B. eine Blasensorte mit einer großen Anzahl von Zahlen, befinden sich die Anweisungen zum Vergleichen / Springen / Tauschen / Inkrementieren der inneren Schleife oben / unten in fast jeder Stapelprobe . Aber (besonders wenn Software groß wird und kaum eine Routine viel "Selbst" -Zeit hat) sind viele Probleme tatsächlich Anrufanweisungen, die Arbeit anfordern, die, wenn klar ist, wie viel sie kostet, nicht wirklich erledigt werden muss.
Mike Dunlavey

3
... Schau dir das an. Ich denke, sie sind fast auf dem richtigen Weg: rotateright.com/zoom.html
Mike Dunlavey

195

gprof (lesen Sie das Papier) existiert aus historischen Gründen. Wenn Sie glauben, dass es Ihnen bei der Suche nach Leistungsproblemen hilft, wurde es nie als solches beworben. Folgendes steht in der Zeitung:

Das Profil kann verwendet werden, um die Kosten verschiedener Implementierungen zu vergleichen und zu bewerten.

Es heißt nicht, dass es verwendet werden kann, um die verschiedenen zu bewertenden Implementierungen zu identifizieren , obwohl dies impliziert, dass dies unter besonderen Umständen möglich ist:

insbesondere wenn festgestellt wird, dass kleine Teile des Programms die Ausführungszeit dominieren.

Was ist mit Problemen, die nicht so lokalisiert sind? Sind die egal? Setzen Sie keine Erwartungen an gprof , die nie dafür beansprucht wurden. Es ist nur ein Messwerkzeug und nur für CPU-gebundene Operationen.

Versuchen Sie dies stattdessen.
Hier ist ein Beispiel für eine 44-fache Beschleunigung.
Hier ist eine 730-fache Beschleunigung.
Hier ist eine 8-minütige Videodemonstration.
Hier ist eine Erklärung der Statistik.
Hier ist eine Antwort auf Kritik.

Es gibt eine einfache Beobachtung über Programme. Bei einer bestimmten Ausführung ist jede Anweisung für einen Bruchteil der Gesamtzeit verantwortlich (insbesondere für callAnweisungen), in dem Sinne, dass die Zeit nicht aufgewendet würde, wenn sie nicht vorhanden wäre. Während dieser Zeit befindet sich die Anweisung auf dem Stapel **. Wenn das verstanden wird, können Sie sehen, dass -

gprof verkörpert bestimmte Mythen über Leistung, wie zum Beispiel:

  1. Diese Programmzählerabtastung ist nützlich.
    Dies ist nur dann sinnvoll, wenn Sie einen unnötigen Hotspot-Engpass haben, z. B. eine Blasensorte mit einer großen Anzahl skalarer Werte. Sobald Sie es beispielsweise mithilfe von Zeichenfolgenvergleich in eine Sortierung ändern, ist dies immer noch ein Engpass, aber beim Programmzähler-Sampling wird dies nicht angezeigt, da sich der Hotspot jetzt im Zeichenfolgenvergleich befindet. Wenn andererseits der erweiterte Programmzähler (der Aufrufstapel) abgetastet wird, wird der Punkt, an dem der Zeichenfolgenvergleich aufgerufen wird, die Sortierschleife, klar angezeigt. Tatsächlich war gprof ein Versuch, die Einschränkungen der Nur-PC-Probenahme zu beseitigen.

  2. Diese Timing-Funktionen sind wichtiger als das Erfassen zeitaufwändiger Codezeilen.
    Der Grund für diesen Mythos ist, dass gprof keine Stapelproben erfassen konnte. Stattdessen werden Funktionen zeitlich festgelegt , ihre Aufrufe gezählt und versucht, das Aufrufdiagramm zu erfassen. Sobald jedoch eine kostspielige Funktion identifiziert wurde, müssen Sie darin nach den Zeilen suchen, die für die Zeit verantwortlich sind. Wenn es Stapelmuster gäbe, die Sie nicht suchen müssten, wären diese Zeilen auf den Beispielen. (Eine typische Funktion haben könnte 100-1000 Anweisungen Eine Funktion. Aufruf ist 1 Anweisung, so etwas , das teure Anrufe lokalisiert ist 2-3 Größenordnungen genauer.)

  3. dass das Anrufdiagramm wichtig ist.
    Was Sie über ein Programm wissen müssen, ist nicht, wo es seine Zeit verbringt, sondern warum. Wenn Zeit in einer Funktion verbracht wird, gibt jede Codezeile auf dem Stapel ein Glied in der Argumentationskette, warum sie vorhanden ist. Wenn Sie nur einen Teil des Stapels sehen können, können Sie nur einen Teil des Grundes dafür sehen, sodass Sie nicht sicher sagen können, ob diese Zeit tatsächlich erforderlich ist. Was sagt Ihnen das Anrufdiagramm? Jeder Bogen zeigt an, dass eine Funktion A für einen Bruchteil der Zeit eine Funktion B aufrief. Selbst wenn A nur eine solche Codezeile hat, die B aufruft, gibt diese Zeile nur einen kleinen Teil des Grundes dafür an. Wenn Sie Glück haben, hat diese Linie vielleicht einen schlechten Grund. Normalerweise müssen Sie mehrere Zeilen gleichzeitig sehen, um einen schlechten Grund zu finden, wenn er vorhanden ist. Wenn A B an mehr als einer Stelle anruft, sagt es Ihnen noch weniger.

  4. Diese Rekursion ist ein heikles, verwirrendes Thema. Dies
    liegt nur daran, dass gprof und andere Profiler die Notwendigkeit erkennen, einen Aufrufgraphen zu generieren und dann den Knoten Zeiten zuzuweisen . Wenn man Samples des Stapels hat, ist der Zeitaufwand für jede Codezeile, die auf Samples erscheint, eine sehr einfache Zahl - der Bruchteil der Samples, auf denen er sich befindet. Wenn es eine Rekursion gibt, kann eine bestimmte Zeile in einem Sample mehrmals vorkommen. Ganz gleich. Angenommen, alle N ms werden Proben genommen, und die Linie erscheint auf F% von ihnen (einzeln oder nicht). Wenn diese Zeile keine Zeit in Anspruch nehmen kann (z. B. durch Löschen oder Verzweigen), verschwinden diese Stichproben und die Zeit wird um F% reduziert.

  5. Diese Genauigkeit der Zeitmessung (und damit eine große Anzahl von Proben) ist wichtig.
    Denken Sie eine Sekunde darüber nach. Wenn sich eine Codezeile auf 3 von fünf Samples befindet, können Sie sie wie eine Glühbirne herausschießen, was ungefähr 60% weniger Zeit kostet. Jetzt wissen Sie, dass Sie, wenn Sie 5 verschiedene Proben genommen hätten, diese möglicherweise nur zweimal oder bis zu 4 Mal gesehen hätten. Die 60% -Messung entspricht also eher einem allgemeinen Bereich von 40% bis 80%. Wenn es nur 40% wären, würden Sie sagen, dass das Problem nicht behoben werden sollte? Was ist also der Zeitpunkt der Genauigkeit, wenn Sie wirklich die Probleme finden möchten ? 500 oder 5000 Proben hätten das Problem genauer gemessen, es aber nicht genauer gefunden.

  6. Das Zählen von Anweisungs- oder Funktionsaufrufen ist nützlich.
    Angenommen, Sie wissen, dass eine Funktion 1000 Mal aufgerufen wurde. Können Sie daraus erkennen, welchen Bruchteil der Zeit es kostet? Sie müssen auch wissen, wie lange es im Durchschnitt dauert, es mit der Anzahl zu multiplizieren und durch die Gesamtzeit zu dividieren. Die durchschnittliche Aufrufzeit kann von Nanosekunden bis Sekunden variieren, sodass die Anzahl allein nicht viel aussagt. Wenn es Stapelstichproben gibt, sind die Kosten für eine Routine oder eine Anweisung nur der Bruchteil der Stichproben, auf denen sie sich befindet. Dieser Zeitanteil könnte im Prinzip insgesamt eingespart werden, wenn die Routine oder Aussage so gestaltet werden könnte, dass sie keine Zeit in Anspruch nimmt. Dies hat also den direktesten Bezug zur Leistung.

  7. dass Samples nicht genommen werden müssen, wenn sie blockiert sind
    Die Gründe für diesen Mythos sind zweierlei: 1) dass PC-Sampling bedeutungslos ist, wenn das Programm wartet, und 2) die Sorge um die Genauigkeit des Timings. Für (1) wartet das Programm jedoch möglicherweise auf etwas, nach dem es gefragt hat, z. B. Datei-E / A, die Sie kennen müssen und die Stapelbeispiele anzeigen. (Natürlich möchten Sie Samples ausschließen, während Sie auf Benutzereingaben warten.) Für (2) Wenn das Programm nur aufgrund der Konkurrenz mit anderen Prozessen wartet, geschieht dies vermutlich auf ziemlich zufällige Weise, während es ausgeführt wird. Während das Programm möglicherweise länger dauert, hat dies keine großen Auswirkungen auf die wichtige Statistik, den Prozentsatz der Zeit, in der sich Anweisungen auf dem Stapel befinden.

  8. dass "Selbstzeit" wichtig ist
    Selbstzeit ist nur dann sinnvoll, wenn Sie auf Funktionsebene und nicht auf Zeilenebene messen und Sie denken, Sie brauchen Hilfe, um zu erkennen, ob die Funktionszeit für rein lokale Berechnungen im Vergleich zu aufgerufenen Routinen verwendet wird. Wenn auf Zeilenebene zusammengefasst wird, repräsentiert eine Linie die Eigenzeit, wenn sie sich am Ende des Stapels befindet, andernfalls repräsentiert sie die Inklusivzeit. In beiden Fällen kostet es den Prozentsatz der Stapelmuster, auf denen es sich befindet, sodass es in beiden Fällen für Sie gefunden wird.

  9. dass Proben mit hoher Frequenz entnommen werden müssen
    Dies beruht auf der Idee, dass ein Leistungsproblem schnell wirken kann und dass Proben häufig sein müssen, um es zu treffen. Wenn das Problem jedoch 20% der Gesamtlaufzeit von 10 Sekunden (oder was auch immer) kostet, hat jede Probe in dieser Gesamtzeit eine 20% ige Chance, es zu treffen, unabhängig davon, ob das Problem auftritt In einem Einzelstück wie diesem
    .....XXXXXXXX...........................
    .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 Proben, 4 Treffer)
    oder in vielen kleinen Stücken wie diesem
    X...X...X.X..X.........X.....X....X.....
    .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 Proben, 3 Treffer)
    beträgt die durchschnittliche Anzahl der Treffer in jedem Fall etwa 1 zu 5, unabhängig davon, wie viele Proben entnommen werden, oder wie wenige. (Durchschnitt = 20 * 0,2 = 4. Standardabweichung = +/- sqrt (20 * 0,2 * 0,8) = 1,8.)

  10. dass Sie versuchen, den Engpass zu finden,
    als ob es nur einen gäbe. Betrachten Sie die folgende Ausführungszeitleiste: vxvWvzvWvxvWvYvWvxvWv.vWvxvWvYvW
    Sie besteht aus wirklich nützlicher Arbeit, dargestellt durch .. Es gibt Leistungsprobleme, vWxYzdie jeweils 1/2, 1/4, 1/8, 1/16, 1/32 der Zeit in Anspruch nehmen. Probenahme vleicht zu finden. Es wird entfernt, sodass
    xWzWxWYWxW.WxWYW
    das Programm nur halb so lange und jetzt Wdie Hälfte der Zeit benötigt und leicht zu finden ist. Es wird entfernt, so dass
    xzxYx.xY
    dieser Vorgang jedes Mal fortgesetzt wird, wenn das größte prozentuale Leistungsproblem entfernt wird, bis nichts mehr zu entfernen ist. Jetzt wird nur noch ausgeführt ., was in 1/32 der vom ursprünglichen Programm verwendeten Zeit ausgeführt wird . Dies ist der Vergrößerungseffekt, wodurch das Entfernen eines Problems den Rest um Prozent vergrößert, weil der Nenner reduziert wird.
    Ein weiterer entscheidender Punkt ist, dass jedes einzelne Problem gefunden werden muss - es fehlt keines der 5. Jedes Problem, das nicht gefunden und behoben wurde, verringert das endgültige Beschleunigungsverhältnis erheblich. Nur einige, aber nicht alle zu finden, ist nicht "gut genug".

HINZUGEFÜGT: Ich möchte nur einen Grund nennen, warum gprof beliebt ist - es wird unterrichtet, vermutlich weil es kostenlos und einfach zu unterrichten ist und es schon lange gibt. Eine schnelle Google-Suche findet einige akademische Institutionen, die sie lehren (oder scheinen):

berkeley bu clemson colorado duke earlham fsu indiana mit msu ncsa.illinois

** Mit Ausnahme anderer Möglichkeiten, die Ausführung von Arbeiten anzufordern, hinterlässt dies keine Spur, die erklärt, warum , z. B. durch das Posten von Nachrichten.


3
@Norman: Ich habe einen Profiler basierend darauf in C für DOS um '93 erstellt. Ich nannte es noch einen weiteren Leistungsanalysator und demonstrierte es bei IEEE-Meetings, aber so weit war es. Es gibt ein Produkt von RotateRight namens Zoom, das nicht zu weit entfernt ist. Unter * nix kann pstack manuell ausgeführt werden. Meine To-Do-Liste für die Arbeit (Pharmakometrie unter Windows) ist ungefähr eine Meile lang, was lustige Projekte ausschließt, ganz zu schweigen von der Familie. Dies könnte nützlich sein: stackoverflow.com/questions/1777669/…
Mike Dunlavey

6
Ich habe immer festgestellt, dass Profiler nicht so nützlich sind, um langsamen Code zu reparieren, und stattdessen selektive Teile des Debugging-Codes verwendet, um die Zeit zu messen, die eine Gruppe von Anweisungen meiner Wahl benötigt, oft unterstützt durch einige triviale kleine Makros oder was auch immer. Ich habe nie zu lange gebraucht, um den Täter zu finden, aber es war mir immer peinlich, wie "Bärenfelle und Steinmesser" vorgehen, wenn "alle anderen" (soweit ich weiß) die ausgefallenen Werkzeuge verwenden. Vielen Dank, dass Sie mir gezeigt haben, warum ich vom Profiler nie die benötigten Informationen erhalten konnte. Dies ist eine der wichtigsten Ideen, die ich auf SO gesehen habe. Gut gemacht!
Wayne Conrad

7
@osgx: Ich will nichts rippen. Es ist wie ein altes Lieblingsauto, einfach und robust, aber es gibt Dinge, die es nicht tut, und wir müssen uns dessen bewusst sein, und nicht nur das, wir müssen aus den Mythen aufwachen. Ich schätze, dass es auf einigen Plattformen schwierig sein kann, Stapelmuster zu erhalten, aber wenn ein Problem so ist, dass gprof es nicht findet, ist die Tatsache, dass es das einzige Werkzeug ist, ein geringer Komfort.
Mike Dunlavey

2
@ Andrew: ... und wenn dieser Grund für einen signifikanten Teil der Stichproben (wie mehr als 1) gilt, befinden sich die Codezeilen, die diese Aktivität eliminieren könnten, in diesen Stichproben. Ein Diagramm kann Ihnen einen Hinweis darauf geben, aber eine nicht große Anzahl von Stapelbeispielen zeigt sie Ihnen einfach an.
Mike Dunlavey

2
@Matt: Beispiele für E / A-Leistungsprobleme wurden folgendermaßen gefunden: 1) Drucken von Protokollnachrichten in eine Datei oder die Konsole, die fälschlicherweise als unbedeutend angesehen wurde. 2) Konvertieren zwischen Text und Doppel in numerischen E / A. 3) Subterranean IO extrahiert internationalisierte Strings während des Startvorgangs. Es stellte sich heraus, dass Strings nicht internationalisiert werden mussten. Ich habe viele Beispiele wie diese getroffen.
Mike Dunlavey

63

Da ich hier nichts gesehen habe, perfwas ein relativ neues Tool zum Profilieren des Kernels und der Benutzeranwendungen unter Linux ist, habe ich beschlossen, diese Informationen hinzuzufügen.

Zunächst einmal - dies ist ein Tutorial zum Erstellen von Linux-Profilenperf

Sie können verwenden, perfwenn Ihr Linux-Kernel größer als 2.6.32 ist oder oprofilewenn er älter ist. Beide Programme erfordern nicht, dass Sie Ihr Programm instrumentieren (wie gproferforderlich). Um das Aufrufdiagramm jedoch korrekt zu erhalten perf, müssen Sie Ihr Programm mit erstellen -fno-omit-frame-pointer. Zum Beispiel : g++ -fno-omit-frame-pointer -O2 main.cpp.

Sie können eine "Live" -Analyse Ihrer Anwendung sehen mit perf top:

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

Oder Sie können Leistungsdaten einer laufenden Anwendung aufzeichnen und anschließend analysieren:

1) So zeichnen Sie Leistungsdaten auf:

perf record -p `pidof a.out`

oder für 10 Sekunden aufnehmen:

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

oder mit Call Graph () aufnehmen

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

2) Um die aufgezeichneten Daten zu analysieren

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

Oder Sie können Leistungsdaten einer Anwendung aufzeichnen und anschließend analysieren, indem Sie die Anwendung auf diese Weise starten und auf das Beenden warten:

perf record ./a.out

Dies ist ein Beispiel für die Profilerstellung eines Testprogramms

Das Testprogramm befindet sich in der Datei main.cpp (ich werde main.cpp am Ende der Nachricht einfügen):

Ich kompiliere es so:

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

Ich benutze, libmalloc_minimial.soda es mit kompiliert wird, -fno-omit-frame-pointerwährend libc malloc ohne diese Option kompiliert zu sein scheint. Dann starte ich mein Testprogramm

./my_test 100000000 

Dann zeichne ich Leistungsdaten eines laufenden Prozesses auf:

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

Dann analysiere ich die Last pro Modul:

perf report --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]

Dann wird die Last pro Funktion analysiert:

perf report --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 ...

Dann werden Anrufketten analysiert:

perf report --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 ...

An diesem Punkt wissen Sie also, wo Ihr Programm Zeit verbringt.

Und das ist main.cpp für den Test:

#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;
}

Ich habe gerade Ihr Beispiel ausgeführt und 5 Stackshots gemacht. Folgendes fanden sie: 40% (ungefähr) der Zeit f1riefen an delete. 40% (ungefähr) der Zeit process_requestriefen an delete. Ein großer Teil des Restes wurde in ausgegeben new. Die Messungen sind grob, aber die Hotspots sind genau bestimmt.
Mike Dunlavey

Was ist ein stackshot? Gibt es das aus pstack?

2
As in my answer, you run it under a debugger and hit ^C at a random time and capture the stack trace. 1) Ich denke, dass Ihre Technik nicht nützlich ist, wenn Sie Leistungsprobleme für ein Programm analysieren müssen, das auf dem Server Ihres Kunden ausgeführt wird. 2) Ich bin nicht sicher, wie Sie diese Technik anwenden, um Informationen für ein Programm mit vielen Threads zu erhalten, die unterschiedliche Anforderungen verarbeiten. Ich meine, wenn das allgemeine Bild ziemlich kompliziert ist.

2
Wie für # 1. Manchmal rufen Kunden an und sagen, dass Ihr Programm langsam arbeitet. Das kann man doch nicht sofort sagen the problem is outside your code, oder? Da benötigen Sie möglicherweise einige Informationen, um Ihren Standpunkt zu unterstützen. In dieser Situation müssen Sie möglicherweise irgendwann Ihre Anwendung profilieren. Sie können Ihren Kunden nicht einfach bitten, gdb zu starten und ^ C zu drücken, um Anrufstapel zu erhalten. Das war mein Punkt. Dies ist ein Beispiel für spielwiese.fontein.de/2012/01/22/… . Ich hatte dieses Problem und die Profilerstellung hat mir sehr geholfen.

2
Wie für # 2. Vereinfachung ist ein guter Ansatz, da stimme ich zu. Manchmal funktioniert es. Wenn ein Leistungsproblem nur auf dem Server eines Kunden auftritt und Sie es nicht auf Ihrem Server reproduzieren können, sind Profile von Nutzen.

21

Versuchen Sie es mit OProfile . Es ist ein viel besseres Tool zum Profilieren Ihres Codes. Ich würde auch Intel VTune vorschlagen .

Mit den beiden oben genannten Tools können Sie die in einer bestimmten Codezeile verbrachte Zeit eingrenzen, Ihren Code mit Anmerkungen versehen, die Assembly anzeigen und festlegen, wie viel bestimmte Anweisungen erforderlich sind. Neben der Zeitmetrik können Sie auch bestimmte Zähler abfragen, z. B. Cache-Treffer usw.

Im Gegensatz zu gprof können Sie jeden Prozess / jede Binärdatei, die auf Ihrem System ausgeführt wird, mit einem der beiden Profile profilieren.


2
Wie auch in der Valgrind-Antwort erwähnt, bietet Zoom von RotateRight ( rotateright.com ) eine viel schönere Oberfläche und ermöglicht die Remote-Profilerstellung.
JanePhanie

mochte kein Profil, es schien willkürlich
Matt Joiner

@Matt einen bestimmten Punkt?
Anycorn

Es war nicht in der Lage, mehr als 10 Sekunden der Ausführung zu bewältigen, bevor statistische Überläufe generiert wurden, die Ausgabe war nicht besonders nützlich und die Dokumentation ist schrecklich.
Matt Joiner

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



Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.