Zuerst einmal, was "[unknown]" bedeutet, ist, dass der Sampler den Namen der Funktion nicht herausfinden konnte, weil es eine System- oder Bibliotheksfunktion ist. Wenn ja, das ist in Ordnung - es ist Ihnen egal, weil Sie für die Zeit in Ihre Code, nicht System-Code für die Dinge verantwortlich suchen suchen.
Eigentlich schlage ich vor, dies ist einer dieser XY questions. Selbst wenn Sie eine direkte Antwort auf das bekommen, was Sie gefragt haben, wird es wahrscheinlich von wenig Nutzen sein. Hier sind die Gründe, warum:
1. CPU Profilieren von geringem Nutzen in einem I/O-gebundene Programm
Die beiden Türme auf die in der Flamme Graph verließ ich tun/O, so dass sie wahrscheinlich viel mehr Mauerzeit als der große Haufen rechts. Wenn diese Flamme Graph von Wand-Zeitproben abgeleitet wurden, anstatt CPU-Zeit Proben, es ist wie die zweite Grafik unten aussehen könnte, die Ihnen sagt, wo die Zeit tatsächlich geht:
What a war der große, saftig aussehende Haufen auf der rechten Seite ist geschrumpft, also ist er nicht annähernd so bedeutend. Auf der anderen Seite sind die E/A-Türme sehr breit. Jeder dieser breiten orangefarbenen Streifen, wenn er in Ihrem Code enthalten ist, stellt eine Chance dar, viel Zeit zu sparen, wenn einige der I/O vermieden werden könnten.
2.Ob das Programm CPU- oder I/O-gebunden ist, können Speedup Möglichkeiten verstecken leicht aus Flamme Graphen
Angenommen, es gibt eine Funktion Foo
ist, die wirklich etwas verschwenderisch tun, dass, wenn man darüber weiß, Sie beheben können. Angenommen, in der Flammenkurve ist es eine dunkelrote Farbe. Angenommen, es wird von zahlreichen Stellen im Code aufgerufen, so dass nicht alle an einer Stelle im Flammengraphen erfasst werden. Vielmehr scheint es in mehreren kleinen Orten hier von schwarzen Konturen gezeigt:
Hinweis, wenn alle diese Rechtecke gesammelt wurden, konnte man sehen, dass es für 11% der Zeit ausmacht, was bedeutet, es lohnt ein Blick auf . Wenn Sie die Zeit halbieren könnten, könnten Sie insgesamt 5,5% sparen. Wenn das, was es tut, tatsächlich vollständig vermieden werden könnte, könnten Sie insgesamt 11% sparen. Jedes dieser kleinen Rechtecke würde zu nichts schrumpfen und den Rest des Graphen damit nach rechts ziehen.
Jetzt zeige ich Ihnen the method I use. Ich nehme eine moderate Anzahl von zufälligen Stack-Samples und untersuche jeden für Routinen, die beschleunigt werden könnten. Das entspricht Proben in der Flamme Graphen zu nehmen, so wie:
Die schlanken vertikalen Linien repräsentieren zwanzig Zufallszeitstapel Proben. Wie Sie sehen können, sind drei von ihnen mit einem X markiert. Das sind diejenigen, die Foo
durchlaufen. Das ist ungefähr die richtige Zahl, denn 11% mal 20 ist 2.2.
(Verwirrt? OK, hier ist eine kleine Wahrscheinlichkeit für Sie. Wenn Sie eine Münze 20 Mal umdrehen, und es hat eine 11% ige Chance Köpfe kommen, wie viele Köpfe würden Sie bekommen? Es ist technisch eine Binomialverteilung. Die am wahrscheinlichsten Zahl, die Sie erhalten würden, ist 2, die nächste am wahrscheinlichsten Zahlen 1 und 3 (Wenn Sie nur 1 bekommen Sie weiter, bis Sie 2 bekommen) Hier ist die Verteilung :)
(die durchschnittliche Anzahl der Proben, die Sie nehmen müssen, um Foo
zweimal zu sehen ist 2/0,11 = 18,2 Proben.)
Wenn man sich diese 20 Stichproben ansieht, mag das etwas abschreckend erscheinen, da sie zwischen 20 und 50 Stufen tief sind. Sie können jedoch grundsätzlich ignorieren den ganzen Code, der nicht deins ist. Überprüfen Sie sie einfach für Ihren Code. Sie werden genau sehen, wie Sie Zeit verbringen, und Sie werden eine sehr grobe Messung davon haben, wie viel. Deep Stacks sind sowohl schlechte Nachrichten als auch gute Nachrichten - sie meinen, der Code kann viel Platz für die Beschleunigung haben, und sie zeigen Ihnen, was diese sind.
Alles, was Sie sehen, dass Sie beschleunigen könnten, , wenn Sie es auf mehr als einer Probe sehen, wird Ihnen eine gesunde Beschleunigung, garantiert. Der Grund, warum Sie es in mehr als einer Probe sehen müssen, ist, wenn Sie es nur an einer Probe sehen, wissen Sie nur, dass seine Zeit nicht Null ist. Wenn Sie es in mehr als einer Probe sehen, wissen Sie immer noch nicht, wie viel Zeit es braucht, aber Sie wissen, dass es nicht klein ist.Im Allgemeinen Here are the statistics.
Kamil Z versuchen Profilierung off-cpu kann, wenn die Aufgabe ist I/O-gebunden, Gregg hat gerade die Skripte veröffentlicht - http://stackoverflow.com/a/28784580/196561 Auch "zufällige Stack-Samples" (zB mit gdb oder sogar mit "perf record -g", dann 'perf script' Rohstapelproben zu nehmen, dann mehrere zufällige Stapel zur manuellen Untersuchung zu nehmen) kann hier nicht helfen, weil 1) es schwierig sein kann, an kurzlebiges Programm anzuhängen (Tracing mit LTTng kann da helfen ...) 2) gdb (oder perf Record) wird immer noch keine Symbolnamen melden, immer noch das Y-Problem von Kamil. Interner node.js/v8 Debugger kann helfen, sie zu lösen. – osgx
@osgx: Bei der manuellen Abtastung müssen Sie sich nicht darum kümmern, ob der E/A-Anschluss gebunden ist oder nicht, es funktioniert genauso. Sie müssen sich nicht darum kümmern, ob eine Routine kurzlebig ist - wenn sie oft genug aufgerufen wird, um einen signifikanten Bruchteil der Zeit zu nutzen, werden Stichproben sie treffen. (Wenn das gesamte Programm zu schnell beendet wird, um eine Probe zu erstellen, füge ich eine temporäre äußere Schleife hinzu.) Ich gehe davon aus, dass man sich in der Position eines Programmierers mit Quellcode und einem Debugger befindet. Für andere Situationen biete ich keinen Rat an. –
@MikeDunlavey Der erste Punkt ist mir nicht klar. Tritt dieses Problem nicht nur auf, wenn der Thread, der profiliert wird, derselbe Thread ist, der die Beispiele generiert? Mit anderen Worten, der Grund dafür, dass der erste Graph keine Wartezeiten für den I/O zeigt, ist, dass er wartet und keine Samples aufgezeichnet haben kann. Wenn andererseits ein anderer Thread die Abtastwerte erzeugt, hätte er die gesamte Warte- und Verarbeitungszeit des Ziel-Threads erfasst, und der zweite Graph würde erzeugt werden. –