Frage

Profil einige C ++ Zahlknirschens Code mit beiden gprof und kcachegrind gibt ähnliche Ergebnisse für die Funktionen, die die meisten der Ausführungszeit beitragen (50-80% bei der Eingabe abhängig), aber für Funktionen zwischen 10-30% sowohl diese Werkzeuge geben unterschiedliche Ergebnisse . Bedeutet es, eine von ihnen nicht zuverlässig ist? Was würde yo hier tun?

War es hilfreich?

Lösung

gprof ist eigentlich ziemlich primitiv. Hier ist, was es tut. 1) Es tastet den Programmzähler mit einer konstanten Geschwindigkeit und Aufzeichnungen, wie viele Proben in jeder Funktion (ohne Zeit landen). 2) Es zählt, wie oft jede Funktion A ruft jede Funktion B. Daraus kann man herausfinden, wie oft jede Funktion insgesamt genannt wurde, und das, was es ist durchschnittlich exklusive Zeit war. Um durchschnittlich inklusive Zeit jeder Funktion es exklusive Zeit breitet sich nach oben in dem Aufrufgraphen.

Wenn Sie erwarten dies eine Art von Genauigkeit zu haben, sollten Sie sich bewusst einige Probleme sein. Erstens, es zählt nur CPU-Zeit-in-Prozess, das heißt, es blind I / O oder anderen Systemaufrufe ist. Zweitens Rekursion es verwirrt. Drittens ist die Prämisse, dass Funktionen auf eine durchschnittliche Laufzeit immer an, egal wann sie genannt werden oder die sie nennt, ist sehr verdächtig. Forth, (grafische Darstellung und deren Anruf) die Vorstellung, dass Funktionen sind, was Sie wissen über müssen, anstatt Codezeilen, ist einfach eine populäre Annahme, nichts weiter. Fünftens, die Vorstellung, dass die Genauigkeit der Messung ist auch relevant auf „Engpässe“ zu finden, ist auch nur eine beliebte Annahme, nichts weiter.

Callgrind können auf der Ebene der Linien arbeiten - das ist gut. Leider teilt es die anderen Probleme.

Wenn Ihr Ziel ist „Engpässe“ zu finden (im Gegensatz zu allgemeinen Messungen bekommen), sollten Sie einen Blick auf Wand-Uhr-Zeit Stapel Sampler nehmen, dass Bericht Prozent-für-Zeile wie Zoom . Der Grund ist einfach, aber möglicherweise nicht vertraut.

Angenommen, Sie haben ein Programm mit einer Reihe von Funktionen gegenseitig aufrufen, die insgesamt 10 Sekunden dauern. Außerdem gibt es einen Sampler, dass die Proben, nicht nur den Programmzähler, sondern der gesamte Call-Stack, und es tut es der ganze Zeit mit einer konstanten Rate, wie 100-mal pro Sekunde. (Ignorieren Sie andere Prozesse für jetzt.)

So am Ende haben Sie 1000 Proben des Call-Stack. Wählen Sie einen beliebigen Codezeile L, das erscheint auf mehr als einer von ihnen. Angenommen, Sie könnten irgendwie diese Linie optimieren, indem sie sie zu vermeiden, entfernen Sie es, oder übergeben Sie aus, um einen wirklich sehr schnellen Prozessor.

Was ist mit diesen Proben passieren würde?

Da die Codezeile L nimmt nun (im Wesentlichen) keine Zeit überhaupt, kann keine Probe traf es, so würden diese Proben nur verschwinden , die Verringerung der Gesamtzahl der Proben und damit die Gesamt Zeit! In der Tat würde die Gesamtzeit, um den Bruchteil der Zeit L reduziert werden hatte auf dem Stapel gewesen, was in etwa der Anteil der Proben, die es enthalten ist.

Ich will nicht zu statistisch bekommen, aber viele Leute denken, dass Sie eine Menge von Proben benötigen, weil sie denken, die Genauigkeit der Messung wichtig ist. Es ist nicht, wenn der Grund, warum Sie das tun ist, um herauszufinden, was Speedup zu beheben zu bekommen. Der Schwerpunkt liegt auf Suche , was zu beheben, nicht auf Messen es. Die Linie L ist auf dem Stapel eine bestimmte Fraktion F der Zeit, nicht wahr? So wird jede Probe mit einer Wahrscheinlichkeit hat F sie zu schlagen, nicht wahr? Genau wie eine Münze werfen. Es gibt eine Theorie dafür, die so genannte Rechtsnachfolge . Er sagt, dass (unter Vereinfachung aber allgemeine Annahmen), wenn Sie eine Münze N-mal drehen, und „Köpfe“ S mal sehen, können Sie die Fairness der Münze F als (im Durchschnitt) (S+1)/(N+2) schätzen. Also, wenn Sie nehmen so wenig wie drei Proben und sehen L auf zwei von ihnen, wissen Sie, was F ist? Natürlich nicht. Aber Sie Sie wissen, im Durchschnitt ist es (2 + 1) / (3 + 2) oder 60% . Also das ist wie viel Zeit konnte man (im Durchschnitt) speichern, indem Sie „Optimierung weg“ Linie L. Und natürlich werden die Stapel Proben zeigten Sie genau , wo Linie L (der „Engpass“ **) ist. Hat es wirklich tha Rollet, das Sie es auf zwei oder drei Dezimalstellen nicht messen haben?

BTW, ist es immun gegen alle anderen oben genannten Probleme .

** Ich halte Anführungszeichen „Engpass“ setzen, weil, was die meisten Software macht langsam hat nichts gemein mit dem Hals einer Flasche. Eine bessere Metapher ist ein „Drain“ -. Etwas, das nur unnötig vergeudet Zeit

scroll top