Welche ist die zuverlässigste profiling-tool gprof oder kcachegrind?
Profiling einige C++ - Anzahl Knirschen code mit beiden gprof
und kcachegrind
führt zu ähnlichen Ergebnissen für die Funktionen, die dazu beitragen, die meisten der Ausführungszeit (50-80%, je nach Eingabe), aber für Funktionen zwischen 10-30% beide tools unterschiedliche Ergebnisse. Bedeutet es, einer von Ihnen ist nicht zuverlässig? Was würde yo hier tun?
Du musst angemeldet sein, um einen Kommentar abzugeben.
gprof ist eigentlich ziemlich primitiv. Hier ist, was es tut.
1) Es samples der Programm-Zähler mit einer Konstanten rate und zeichnet auf, wie viele samples land in jeder Funktion (exklusiv-Zeit).
2) Es zählt, wie oft jede Funktion A ruft jede Funktion B.
Aus, die es finden kann, wie oft jede Funktion aufgerufen wurde, in der Summe, und was es durchschnittlich exklusive Zeit war.
Um Durchschnitt-inclusive-Zeit, die jede Funktion, die es propagiert, exklusive Zeit nach oben in der call-graph.
Wenn Sie erwarten, dass dies zu einer Art von Genauigkeit, die Sie sollten sich bewusst sein, einige Probleme.
Erstens, es zählt nur CPU-Zeit-in-Verfahren, d.h. es wird blind auf die I/O-oder anderen system aufruft.
Zweite Rekursion verwirrt es.
Dritte, die Prämisse, dass die Funktionen sich immer auf eine Durchschnittliche Laufzeit, egal Wann Sie gerufen werden oder wer Sie nennt, ist sehr verdächtig.
Her mit der Vorstellung, dass Funktionen (und Ihre call graph) sind das, was Sie brauchen, um zu wissen, anstatt Zeilen code, ist eine beliebte Vermutung, nichts mehr.
Fünfte, die Vorstellung, dass die Genauigkeit der Messung ist auch relevanten zu finden, "Engpässe" ist auch nur eine beliebte Annahme ist, nichts mehr.
Callgrind arbeiten können auf der Ebene der Linien - das ist gut. Leider teilt er die anderen Probleme.
Wenn Ihr Ziel ist es, "Engpässe" (im Gegensatz zu bekommen Allgemeine Messungen), sollten Sie einen Blick auf die wall-clock-time-stack-Sampler, die Berichts-Prozent-by-line, wie Zoom.
Der Grund ist einfach, aber möglicherweise nicht geläufig sind.
Angenommen, Sie haben ein Programm mit einer Reihe von Funktionen Aufruf von jeder anderen, dass dauert insgesamt 10 Sekunden. Auch, es ist ein sampler, die samples, und nicht nur die Programm-Zähler, sondern den gesamten call-stack, und es tut die ganze Zeit mit einer Konstanten rate, wie 100-mal pro Sekunde. (Ignorieren Sie andere Prozesse für jetzt.)
Also am Ende haben Sie 1000 Proben von den call-stack.
Wählen Sie jede Zeile code L, die angezeigt wird auf mehr als einer von Ihnen.
Angenommen, Sie könnten irgendwie optimieren, dass die Linie, indem es vermeidet, es zu entfernen, oder übergeben Sie es aus, um einen wirklich schnellen Prozessor.
Was passieren würde, solche Proben?
Da diese Codezeile L nimmt nun (im wesentlichen) überhaupt keine Zeit, die Probe nicht treffen können, so dass diese Proben würden nur verschwinden, die Verringerung der Gesamtzahl der Proben, und somit die gesamte Zeit!
In der Tat die gesamte Zeit würde verringert werden, indem der Bruchteil der Zeit, die L hatte auf dem stack, das ist grob der Anteil der Proben, die enthalten es.
Ich will nicht zu statistischen, aber viele Leute denken, Sie müssen viel Proben, weil Sie denken, dass die Genauigkeit der Messung ist wichtig.
Es ist nicht, wenn der Grund, warum Sie dies tun ist, um herauszufinden, was zu beheben ist, um Beschleunigung.
Der Schwerpunkt liegt auf finden, was zu korrigieren ist, nicht auf Messung es.
Linie L ist, die auf dem stack einen Bruchteil F der Zeit, richtig?
Jede Probe hat eine Wahrscheinlichkeit F, es zu schlagen, richtig? Genauso wie das werfen einer Münze.
Es gibt eine Theorie dieser, genannt die Regel der Nachfolge.
Es besagt, dass (unter der Vereinfachung, aber Allgemeine Annahmen), wenn Sie eine Münze werfen N-mal, und zu sehen, "Köpfe" S Zeiten, können Sie schätzen die fairness der Münze F (durchschnittlich)
(S+1)/(N+2)
.Also, wenn Sie nehmen Sie so wenig wie drei Proben, und finden Sie L auf zwei von Ihnen, wissen Sie, was F? Natürlich nicht.
Aber Sie tun wissen, im Durchschnitt ist es (2+1)/(3+2) oder 60%.
Das ist also, wie viel Zeit Sie sparen könnten (im Durchschnitt) durch "Optimierung" Weg der Linie L.
Und, natürlich, die stack-Proben zeigten Sie genau, wo die Linie L (der "Flaschenhals"**) ist.
Tat es wirklich wichtig, dass Sie nicht zu Messen, es auf zwei oder drei Nachkommastellen?
BTW, es ist immun gegen alle anderen oben genannten Probleme.
**Ich halten, setzen Sie Anführungszeichen um "Flaschenhals", denn was macht die meisten software-slow hat nichts mit dem Hals einer Flasche.
Eine bessere Metapher ist ein "drain" - etwas, was nur unnötig Zeit vergeudet.
gprof
's-timing-Daten ist die statistische (Lesen Sie darüber in details von profiling docs).Auf der anderen Seite
KCacheGrind
verwendetvalgrind
die eigentlich interpretiert den code.So
KCacheGrind
werden kann "genauer" (auf Kosten von mehr overhead) wenn die CPU nach dem Vorbild vonvalgrind
nah an Ihren realen CPU.Welche man zu wählen, hängt auch davon ab, welche Art von overhead, die Sie behandeln können. In meiner Erfahrung
gprof
fügt weniger Verwaltungsaufwand zur Laufzeit (Ausführungszeit ist), aber es ist mehr aufdringlich (also-pg
fügt den code, der für jeden Ihrer Funktionen). So kann je nach situation ein oder die andere besser geeignet.Für "besser"
gprof
Daten, ausführen von code mehr (und auf eine möglichst Breite Palette von test-Daten Sie können). Je mehr Sie haben, desto besser werden die Messungen statistisch ausgewertet.