Wie kann ich Profil C++ - code läuft auf Linux?
Ich habe eine C++ - Anwendung, läuft auf Linux, die ich bin in den Prozess der Optimierung. Wie kann ich ermitteln, welche Bereiche der mein code langsam ausgeführt werden?
- Wenn Sie mehr Daten über Ihre Entwicklungs-stack könnte man besser Antworten. Es gibt Profiler von Intel und Sonne, aber Sie müssen verwenden Sie Ihre Compiler. Ist das eine option?
- Es ist bereits beantwortet auf den folgenden link: stackoverflow.com/questions/2497211/...
- Die meisten Antworten sind
code
Profiler. Jedoch, priority inversion, cache-aliasing, Ressourcenkonflikte, etc.. können alle Faktoren bei der Optimierung und Leistung. Ich denke, dass die Menschen Lesen Informationen in meinen langsamen code. FAQs verweisen auf diesen thread. - CppCon 2015: Chandler Carruth "Tuning C++: Benchmarks und CPUs und Compiler! Oh My!"
- Ich verwendet, um zu verwenden pstack nach dem Zufallsprinzip, die meisten der Zeit, wird das drucken der meisten typischen stack, wo das Programm die meiste Zeit, daher zeigte auf den Engpass.
- cachegrind/callgrind ?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Ihr Ziel ist es, einen profiler verwenden, verwenden Sie einen der Vorschläge.
Allerdings, wenn Sie in Eile sind, und Sie können manuell unterbrechen Ihr Programm unter dem debugger, während es subjektiv zu langsam ist, gibt es einen einfachen Weg, um performance-Problemen.
Nur halt es mehrere Male, und jedes mal, wenn die Aufrufliste betrachten. Wenn es ein code, der verschwendet einen gewissen Prozentsatz der Zeit, 20% oder 50% oder was auch immer, ist die Wahrscheinlichkeit, dass Sie fangen in der Tat auf jede Probe. Also das ist in etwa der Prozentsatz der Proben, auf denen Sie sehen. Es gibt keine gebildeten Rätselraten erforderlich.
Wenn Sie tun, haben Sie eine Vermutung, was das problem ist, dies zu beweisen oder zu widerlegen.
Sie können mehrere performance-Probleme in verschiedenen Größen. Wenn Sie reinigen, eine von Ihnen, die übrigen einen größeren Anteil, und werden leichter zu erkennen, auf nachfolgende Durchgänge.
Diese Vergrößerung Wirkung, wenn verstärkt über mehrere Probleme, führt zu wirklich massiven speedup-Faktoren.
Nachteil: Programmierer neigen dazu, skeptisch zu sein, von dieser Technik, es sei denn, Sie haben es sich selbst. Sie werden sagen, dass Profiler geben Sie diese Informationen, aber das ist nur wahr, wenn Sie Proben den gesamten call-stack, und dann lassen Sie Sie untersuchen eine zufällige Reihe von Proben. (Die Zusammenfassungen sind, wo die Einsicht verloren geht.) Call-Graphen nicht geben Sie die gleichen Informationen, weil
Werden Sie auch sagen, es funktioniert nur auf Spielzeug-Programme, wenn tatsächlich es funktioniert auf jedem Programm, und es scheint zu funktionieren besser auf größere Programme, weil Sie dazu neigen, mehr Probleme zu finden.
Sie werden sagen, dass es manchmal Dinge findet, die keine Probleme, aber das ist nur wahr, wenn man etwas sehen einmal. Wenn Sie sehen, ein problem auf mehr als eine Probe, es ist real.
P. S. Dies ist auch bei multi-thread-Programme, wenn es einen Weg gibt, zu sammeln, call-stack-Proben des thread-Pools an einem Punkt in der Zeit, als es in Java.
P. P. S Als eine grobe Verallgemeinerung, die mehrere Ebenen der Abstraktion, die Sie haben in Ihre software, desto wahrscheinlicher werden Sie finden, dass das die Ursache von performance-Problemen und die Chance zu bekommen speedup).
Hinzugefügt: Es ist vielleicht nicht offensichtlich sein, aber der stack sampling-Technik, die funktioniert genauso gut in der Gegenwart von Rekursion. Der Grund dafür ist, dass die Zeit, die gespeichert werden, durch Entfernung einer Anweisung wird approximiert durch den Anteil der Proben in denen es, unabhängig von der Anzahl der Zeiten kann es vorkommen innerhalb einer Probe.
Einen anderen Einwand, den ich oft höre, ist: "Es wird halt irgendwo zufällig, und Sie verfehlen das eigentliche problem".
Das kommt von einem Konzept vor, was das wirkliche problem ist.
Eine wesentliche Eigenschaft der performance-Probleme ist, dass Sie trotzen Erwartungen.
Sampling-sagt Sie etwas, ist ein problem, und Ihre erste Reaktion Unglauben.
Das ist natürlich, aber Sie können sicher sein, wenn es ein problem findet, es ist real, und Umgekehrt.
HINZUGEFÜGT: Lassen Sie mich eine Bayes ' sche Erklärung, wie es funktioniert. Angenommen, es gibt eine Instruktion
I
(call oder anderweitig), die auf dem Aufruf-stack einen Bruchteilf
von der Zeit (und damit Kosten viel). Zur Vereinfachung nehmen wir an, wir wissen nicht, wasf
ist, aber nehme an, es ist entweder 0.1, 0.2, 0.3, ... 0.9, 1.0, und die Vorherige Wahrscheinlichkeit für jede dieser Möglichkeiten ist 0.1, also alle diese Kosten sind ebenso wahrscheinlich, a-priori.Dann nehmen wir an, wir nehmen nur 2 stack-Proben, und wir sehen Sie Anweisung
I
auf beiden Proben, bezeichnet die Beobachtungo=2/2
. Dies gibt uns neue Schätzungen über die Häufigkeitf
vonI
nach dieser:Die Letzte Spalte sagt, dass, zum Beispiel, die Wahrscheinlichkeit, dass
f
>= 0,5 92%, von den vor der übernahme von 60%.Nehme an, dass die vorherigen Annahmen unterschiedlich sind. Angenommen, wir nehmen an P(f=0,1) ist .991 (fast sicher), und alle anderen Möglichkeiten sind fast unmöglich (0.001). In anderen Worten, unsere Vorherige Gewissheit, dass
I
ist Billig. Dann erhalten wir:Nun heißt es P(f >= 0.5) liegt bei 26%, von der vor der Annahme von 0,6%. So Bayes ermöglicht uns die Aktualisierung unserer Schätzung der voraussichtlichen Kosten für die
I
. Wenn die Menge der Daten klein ist, es sagt uns nicht genau, was das Kosten wird, nur, dass es groß genug zu sein Wert Festsetzung.Noch einen anderen Weg um es zu betrachten, heißt die Regel Der Nachfolge.
Wenn Sie eine Münze werfen 2 mal, und Kopf beide Male, was sagt Sie über die voraussichtliche Gewichtung der Münze?
Der ANGESEHENE Weise zu beantworten, ist zu sagen, dass es eine Beta-Verteilung mit Mittelwert (Anzahl der Treffer, + 1) /(Anzahl der versuche + 2) = (2+1)/(2+2) = 75%.
(Der Schlüssel ist, dass wir sehen
I
mehr als einmal. Wenn wir nur sehen, es einmal, das sagt uns nicht viel, außer, dassf
> 0.)So, auch eine sehr kleine Anzahl von Proben kann uns sagen viel über die Kosten von Anweisungen, die es sieht. (Und es wird sehen, wie Sie mit einer Frequenz, im Durchschnitt proportional zu Ihren Kosten. Wenn
n
Proben genommen, undf
ist der Preis, der dannI
erscheint aufnf+/-sqrt(nf(1-f))
Proben. Beispieln=10
,f=0.3
, das ist3+/-1.4
Proben.)HINZUGEFÜGT, um ein intuitives Gefühl für die Differenz zwischen mess-und random-stack sampling:
Es sind Profiler nun, dass die Probe den Stapel auch an der wall-clock-Zeit, aber , was dabei heraus kommt ist-Messungen (oder heißen Pfad, oder hot-spot, von dem ein "Engpass" kann leicht zu verstecken). Was Sie nicht zeigen (und Sie könnte leicht) ist das eigentliche Proben selbst. Und wenn es Ihr Ziel ist finden der Flaschenhals, der die Anzahl von Ihnen, die Sie brauchen, um zu sehen ist, durchschnittlich, 2 geteilt durch den Bruchteil der Zeit, die es dauert.
Also, wenn es dauert 30% der Zeit, 2/.3 = 6.7 Proben, im Durchschnitt wird es zeigen, und die chance, dass 20 Proben zeigt, ist es bei 99,2%.
Hier ist ein off-the-Manschette Abbildung der Unterschied zwischen der Prüfung die Messungen und Prüfung der stack-Proben.
Der Engpass werden könnte, eine große blob, wie diese, oder die zahlreichen kleinen, es macht keinen Unterschied.
Messung ist horizontal; er sagt Ihnen, was Bruchteil der Zeit bestimmte Routinen nehmen.
Sampling ist vertikal.
Wenn es irgendeinen Weg gibt, das zu vermeiden, was das ganze Programm macht in diesem moment und wenn Sie sehen, es auf eine zweite Probe, Sie haben gefunden den Engpass.
Das ist, was macht den Unterschied - zu sehen, der ganze Grund für die Zeit, die ausgegeben werden, nicht nur, wie viel.
P(f >= x)
korrigieren oder meinst du das wirklichP(f >= x | o=2/2)
?write
), so dass Ihr Programm ist eher prempted auf eine zufälligewrite()
(wie die Protokollierung auf der standard-Ausgabe) als verdrängt werden, auf die tatsächlichen Berechnungen.kill()
. Aber die Tötung muss ausgeführt werden, wenn Sie ausführt, töten(). Und auf einem single-core-system, wenn die Tötung Prozess läuft, dann wird das Programm Sie wollen zu töten, nicht ausgeführt; es wurde prempted vor. Wenn Vorkaufsrecht ist deterministisch, dann ist es weniger random.foo
dass nur angezeigt wird, irgendwann in der Mitte jedes dieser vielen vertikalen schießt, es wird nicht schnappen Sie sich Ihre Aufmerksamkeit. OTOH, wenn Sie nur 5, 10 oder 20 Proben, drucken Sie Sie aus, und betrachten Sie Sie mit Ihre Augäpfel sehen Siefoo
auf Sie im Verhältnis in etwa gleich, was Sie sparen könnten, wenn Sie könnte es machen, keine Zeit nehmen, und Sie werden sehen, was der Grund ist, warum es wird genannt. Die Chancen sind, müssen Sie nicht so oft aufgerufen werden. Dies ist, was ich versuche rüberzubringen.poll, xcb_wait_for_reply, XReply, intel_update_renderbuffers, intel_prepare_render
. Jede dieser aktiv ist, über 2/3 der Zeit, also die Chancen stehen Recht gut, da nur 3 Proben identifiziert hätte für Sie als Routinen, die Sie anschauen sollte.memcpy()
ing in einer X-video driver, aber außergewöhnliche Behauptungen erfordern außergewöhnliche (Mengen) Beweise, so ich erfunden, so etwas wie dieses on-the-fly. Auch nützlich, wenn man die terminal-Fenster hält die render-Schleife, so konnte ich nicht einmal diese Proben anders 😛 werde ich weitere Informationen hinzufügen, um das tool bald.Können Sie Valgrind mit den folgenden Optionen
Generiert es eine Datei namens
callgrind.out.x
. Sie können dann mitkcachegrind
tool um diese Datei zu Lesen. Es wird Ihnen eine grafische Analyse der Dinge mit den Ergebnissen, wie die Linien Kosten wie viel../gprof2dot.py -f callgrind callgrind.out.x | dot -Tsvg -o output.svg
Ich nehme an, Sie sind mit dem GCC Compiler. Die standard-Lösung wäre Profil mit gprof.
Werden Sie sicher, dass Sie
-pg
Zusammenstellung vor profiling:Ich habe nicht versucht es noch aber ich habe gehört, gute Dinge über google-perftools. Es ist definitiv einen Versuch Wert.
Stellt sich die Frage,hier.
Ein paar andere Schlagworte, wenn
gprof
nicht der job für Sie tun: Valgrind, Intel VTune, Sonne DTrace.Neueren Kernel (z.B. die aktuelle Ubuntu-Kernel) mit dem neuen 'perf' - tools (
apt-get install linux-tools
) AKA perf_events.Diese kommen mit klassischen sampling-Profiler (Mann-Seite) sowie die genial timechart!
Das wichtigste ist, dass diese Werkzeuge können system-profiling - und nicht nur Prozess-profiling - Sie zeigen die Interaktion zwischen threads, Prozessen und der kernel und lassen Sie Sie verstehen, scheduling und I/O Abhängigkeiten zwischen Prozessen.
perf report
scheint mir die Funktionsnamen mit den Eltern nennen... (also es ist sozusagen ein umgekehrtes butterfly-Ansicht)gprof2dot
undperf script
. Sehr nettes tool!perf
gibt es auf Archiv.li/9r927#Auswahl-767.126-767.271 (Warum die Götter SO beschlossen zu löschen, die Seite von der knowledge base ist mir schleierhaft....)Ich würde Valgrind und Callgrind als Basis für meine profiling-tool-suite. Was wichtig zu wissen ist, dass Valgrind ist im Grunde eine Virtuelle Maschine:
Callgrind ist ein profiler baut auf, der. Der Hauptvorteil ist, dass Sie nicht haben ausführen Ihre Bewerbungsunterlagen, für Stunden, um zuverlässige Ergebnis. Noch eine Sekunde laufen, ist ausreichend, um rock-solid, verlässliche Ergebnisse, da Callgrind ist ein nicht antasten profiler.
Einem anderen tool bauen auf Valgrind ist Massiv. Ich benutze es zum Profil heap-Speicher-Nutzung. Es funktioniert Super. Was es tut, ist, dass es Ihnen snapshots der Speicher-Nutzung -- detaillierte Informationen, WAS das hält, WAS Prozentsatz des Speichers, und WER hatte ihn dort. Solche Informationen verfügbar zu unterschiedlichen Zeitpunkten der Anwendung auszuführen.
Die Antwort auf ausführen
valgrind --tool=callgrind
ist nicht ganz vollständig, ohne einige Optionen. Wir in der Regel nicht wollen, um Profil 10 Minuten des langsamen Systemstart unter Valgrind und Profilieren möchten unser Programm, wenn es dabei einige Aufgabe.Also das ist, was ich empfehlen. Führen Sie das Programm zuerst:
Nun, wenn es funktioniert und wir wollen Sie auf " Profilerstellung starten sollten wir laufen in ein anderes Fenster:
Dreht dieser Profilierung auf. Um es zu deaktivieren und stoppen Sie die ganze Aufgabe, die wir verwenden könnten:
Nun haben wir einige Dateien namens callgrind.aus.* im aktuellen Verzeichnis. Zu sehen, verwenden Sie die profiling-Ergebnisse:
Empfehle ich, im nächsten Fenster klicken Sie auf "Self" Spalten-header, sonst zeigt es, dass die "main()" ist sehr zeitaufwändige Aufgabe. "Selbst" zeigt, wie viel jede Funktion selbst nahm sich die Zeit, nicht zusammen mit Angehörigen.
callgrind_control
in ein anderes Fenster zu aktivieren profiling on/off? es scheint mir, wie es wäre viel besser konstruieren Sie ein minimales Programm, das enthält nur das, was Sie wollen Profil, und dann Profil-das ganze Programm.CALLGRIND_TOGGLE_COLLECT
zum aktivieren/deaktivieren der Sammlung programmgesteuert; siehe stackoverflow.com/a/13700817/288875Dies ist eine Reaktion auf Nazgob ist Gprof Antwort.
Habe ich mit Gprof die letzten paar Tage und haben schon drei wichtige Einschränkungen, von denen habe ich nicht gesehen, dokumentiert überall sonst (noch):
Es nicht richtig funktioniert auf multi-threaded-code, es sei denn, Sie verwenden eine Abhilfe
Den call-graph wird verwirrt von Funktionszeigern. Beispiel: ich habe eine Funktion namens
multithread()
was mir ermöglicht multi-thread eine bestimmte Funktion in einem angegebenen array (beide als Argumente übergeben wurden). Gprof jedoch die Aussicht auf alle Anrufe zumultithread()
als gleichwertig für die Berechnung der verbrachten Zeit in die Kinder. Da einige Funktionen, die ich übergeben, ummultithread()
viel länger dauern als andere, mein call Graphen sind meist nutzlos. (An die, die Fragen, ob threading ist die Frage hier: Nein,multithread()
können Optional und in diesem Fall, alles nacheinander auf den aufrufenden thread nur).Er sagt hier, dass "... die Anzahl der Anrufe zahlen sind abgeleitet von der Zählung, nicht sampling. Sie sind ganz genau...". Doch ich finde meinen call-graph gibt mir 5345859132+784984078 als call-stats zu meiner am häufigsten aufgerufenen Funktion, wo die erste Zahl soll direkte Anrufe, und der zweite rekursive Aufrufe (die sind alle von selbst). Da dies bedeutete, ich hatte einen bug, ich habe in langen (64-bit) Zähler in den code, und habe die gleichen wieder zu laufen. Meine zählt: 5345859132 direkte und 78094395406 selbst-rekursiven Aufrufe. Es gibt eine Menge von stellen, so werde ich darauf hinweisen, die rekursive Aufrufe, die ich Messen sind 78bn, versus 784m von Gprof: ein Faktor 100 unterschiedlich. Beide Läufe waren single threaded und unoptimised code, eine kompilierte
-g
und die anderen-pg
.Diese wurde GNU Gprof (GNU Binutils für Debian) 2.18.0.20080103 läuft unter 64-bit Debian Lenny, wenn das hilft niemandem.
Verwenden, Valgrind, callgrind und kcachegrind:
generiert callgrind.aus.x. Lesen Sie mit kcachegrind.
Nutzung von gprof (add-pg):
(nicht so gut für multi-threads, Funktionszeiger)
Verwendung von google-perftools:
Verwendet sampling-Zeit, I/O-und CPU-Engpässe aufgedeckt werden.
Intel VTune ist das beste (kostenlos für pädagogische Zwecke).
Andere: AMD Codeanalyst (da ersetzt mit AMD CodeXL), OProfile, 'perf' - tools (apt-get install linux-tools)
Für single-threaded-Programme, die Sie verwenden können, igprof, Die Ignominous Profiler: https://igprof.org/ .
Es ist ein sampling-profiler, entlang der Linien von der... langen... Antwort von Mike Dunlavey, die werden als Geschenk zu Verpacken die Ergebnisse in einem leicht durchsuchbaren call-stack Baum, versehen mit der Zeit oder Speicher ausgegeben, in jeder Funktion, die entweder kumulativ oder pro-Funktion.
Diese sind die zwei Methoden, die ich für die Beschleunigung mein code:
Für CPU-gebundene Anwendungen:
Für I/O-gebundene Anwendungen:
N. B.
Wenn Sie nicht über einen profiler, verwenden Sie den Armen Mann profiler. Treffer pause beim Debuggen der Anwendung. Die meisten Entwickler suites brechen in der Montage mit auskommentierte Zeile zahlen. Sie sind statistisch wahrscheinlich, um land, in einer region, die Essen die meisten von Ihrer CPU-Zyklen.
Für die CPU ist der Grund für die Profilerstellung in DEBUG - Modus ist, denn wenn Ihr versucht profiling in RELEASE - Modus, der compiler geht zu reduzieren, Mathematik, Vektorisieren von Schleifen und inline-Funktionen, die dazu neigt, zu Klumpen, den code in eine un-mappable Durcheinander, wenn es zusammengebaut ist. Eine un-mappable Chaos bedeutet profiler werden nicht in der Lage, klar zu identifizieren, was dauert da so lange, weil die Versammlung kann nicht entsprechen den source-code unter Optimierung. Wenn Sie die Leistung benötigen (z.B. timing-empfindlich) von RELEASE - Modus, deaktivieren Sie die debugger-Funktionen als notwendig, um eine nutzbare Leistung.
Für I/O-bound, der profiler kann immer noch erkennen, I/O-Operationen in RELEASE Modus, weil der I/O-Operationen sind entweder extern verlinkt, um eine shared library (die meiste Zeit) oder im schlimmsten Fall, wird in einem sys-Aufruf interrupt-Vektor (die ist auch leicht erkennbar durch den profiler).
Erwähnenswert ist auch
Habe ich verwendet HPCToolkit und VTune und Sie sind sehr effektiv bei der Suche nach der lange Stange in das Zelt und müssen nicht Ihren code neu kompiliert werden (mit Ausnahme, dass Sie müssen verwenden Sie-g -O oder RelWithDebInfo Art zu bauen, die in CMake um sinnvolle Ausgabe). Ich habe gehört, TAU ist ähnlich in Funktionen.
Können Sie die iprof Bibliothek:
https://gitlab.com/Neurochrom/iprof
https://github.com/Neurochrom/iprof
Es ist cross-Plattform und ermöglicht es Ihnen nicht um die Leistung zu Messen von Sie Ihre Anwendung auch in Echtzeit. Sie können auch paar Sie mit einem live-Graphen.
Full disclaimer: ich bin der Autor.
Können Sie eine logging-Frameworks wie
loguru
, denn es beinhaltet Zeitstempel und Gesamt-Betriebszeit, die verwendet werden können, schön für die Profilerstellung:Bei der Arbeit haben wir ein wirklich nettes Werkzeug, das uns hilft, monitoring, was wir wollen, in Bezug auf die Zeitplanung. Dies war nützlich, viele Male.
Es ist in C++ und muss an Ihre Bedürfnisse angepasst werden. Kann ich leider nicht teilen code, nur Konzepte.
Verwenden Sie die "großen"
volatile
Puffer mit Zeitstempel und Ereignis-ID, können Sie post-mortem-dump oder nach dem stoppen des logging-Systems (und dump diese in eine Datei zum Beispiel).Rufen Sie den so genannten großen Puffer, mit allen Daten und einem kleinen interface analysiert es und zeigt Ereignisse mit dem Namen (up/down + Wert) wie ein Oszilloskop mit Farben (konfiguriert in
.hpp
- Datei).Passen Sie die Menge der Ereignisse, die generiert werden, konzentrieren sich ausschließlich auf das, was Sie sich wünschen. Es hat uns geholfen, eine Menge für scheduling-Probleme und verbraucht die Menge an CPU-wollten wir-basierend auf die Menge der protokollierten Ereignisse pro Sekunde.
Benötigen Sie 3 Dateien :
Dem Konzept ist die Definition von Ereignissen in
tool_events_id.hpp
so :Definieren Sie auch ein paar Funktionen in
toolname.hpp
:Immer dort, wo Sie code, den Sie verwenden können :
Den
probe
- Funktion verwendet ein paar Fließband abrufen-die-Uhr-timestamp so schnell wie möglich und setzt dann einen Eintrag in den Puffer ein. Wir haben auch eine Atomare Inkrement-sicher finden Sie einen index, in dem zum speichern der log-event.Natürlich Puffer ist kreisförmig.
Hoffe die Idee ist nicht verschleiert durch den Mangel an Beispiel-code.
Als niemand erwähnte Arm ANSEHEN würde, würde ich es hinzufügen, da ich persönlich erfolgreich Anzeigen zu Profil einen C++ wissenschaftlichen Programm.
Arm MAP ist der profiler für die parallele Multithread-oder single-threaded C -, C++ -, Fortran-und F90-codes. Es bietet in-depth-Analyse und-Engpass lokalisiert, um die Quellcode-Zeile. Im Gegensatz zu den meisten profilern, es ist entworfen, um in der Lage zu Profil, pthreads, OpenMP oder MPI für parallele und threaded code.
KARTE ist eine kommerzielle software.