[c++] Wie kann ich C ++ - Code profilieren, der unter Linux läuft?


Answers

Sie können Valgrind mit den folgenden Optionen verwenden

valgrind --tool=callgrind ./(Your binary)

Es wird eine Datei namens callgrind.out.x . Sie können dann das Tool kcachegrind verwenden, um diese Datei zu lesen. Es wird Ihnen eine grafische Analyse von Dingen mit Ergebnissen geben, wie welche Zeilen wie viel kosten.

Question

Ich habe eine C ++ - Anwendung, die auf Linux läuft und die ich gerade optimiere. Wie kann ich feststellen, welche Bereiche meines Codes langsam ausgeführt werden?




Verwenden Sie Valgrind, Callgrind und Kcachegrind:

valgrind --tool=callgrind ./(Your binary)

erzeugt callgrind.out.x. Lesen Sie es mit kcachegrind.

Verwende gprof (add -pg):

cc -o myprog myprog.c utils.c -g -pg 

(nicht so gut für Multithreads, Funktionszeiger)

Verwenden Sie google-perftools:

Verwendet Zeit-Sampling, zeigt I / O und CPU-Engpässe werden aufgedeckt.

Intel VTune ist das Beste (kostenlos für Bildungszwecke).

Andere: AMD Codeanalyst, OProfile, 'perf' Werkzeuge (apt-get install linux-tools)




Neuere Kernel (zB die neuesten Ubuntu-Kernel) werden mit den neuen "perf" perf_events ( apt-get install linux-tools ) AKA perf_events .

Diese kommen mit klassischen Sampling-Profilern ( man-page ) sowie dem tollen timechart !

Wichtig ist, dass diese Tools Systemprofilerstellung und nicht nur Prozessprofilierung sein können - sie können die Interaktion zwischen Threads, Prozessen und dem Kernel zeigen und Ihnen die Planung und E / A-Abhängigkeiten zwischen Prozessen verständlich machen.




Dies ist eine Antwort auf Nazgobs Gprof-Antwort .

Ich habe Gprof in den letzten Tagen verwendet und habe bereits drei signifikante Einschränkungen gefunden, von denen ich (noch) nirgendwo anders dokumentiert habe:

  1. Es funktioniert nicht ordnungsgemäß auf Multithread-Code, es sei denn, Sie verwenden eine workaround

  2. Das Aufrufdiagramm wird durch Funktionszeiger verwirrt. Beispiel: Ich habe eine Funktion namens multithread (), die es mir ermöglicht, eine bestimmte Funktion über ein spezifiziertes Array (beide als Argumente übergeben) zu migrieren. Gprof betrachtet jedoch alle Aufrufe von Multithread () als äquivalent für die Rechenzeit, die für Kinder aufgewendet wird. Da einige Funktionen, die ich an Multithread () übergebe, viel länger dauern als andere, sind meine Aufrufgraphen meistens nutzlos. (Für diejenigen, die sich fragen, ob Threading das Problem hier ist: Nein, multithread () kann optional und tat in diesem Fall alles sequenziell nur auf dem aufrufenden Thread).

  3. Es heißt here dass "... die Anzahl der Rufnummern durch Zählen, nicht durch Abtasten abgeleitet wird. Sie sind vollkommen genau ...". Aber ich finde mein Anrufdiagramm, das mir 5345859132 + 784984078 als Anrufstatistik zu meiner am meisten genannten Funktion gibt, wo die erste Nummer direkte Anrufe sein sollen, und die zweiten rekursiven Anrufe (die alle von selbst sind). Da dies bedeutete, dass ich einen Fehler hatte, steckte ich lange (64-Bit-) Zähler in den Code und führte denselben Lauf erneut aus. Meine zählt: 5345859132 direkt und 78094395406 selbstrekursive Aufrufe. Es gibt viele Stellen dort, also werde ich darauf hinweisen, dass die rekursiven Aufrufe, die ich messe, 78bn sind, gegenüber 784m von Gprof: ein Faktor von 100 verschieden. Beide Läufe waren single-threaded und nicht optimierter Code, einer kompiliert -g und der andere -pg.

Das war GNU Gprof (GNU Binutils für Debian) 2.18.0.20080103 läuft unter 64-Bit Debian Lenny, wenn das irgendjemandem hilft.




Für single-threaded Programme können Sie igprof , den Ignominous Profiler verwenden: https://igprof.org/ .

Es ist ein Sampling-Profiler, ähnlich wie bei ... long ... Antwort von Mike Dunlavey, der die Ergebnisse in einen durchsuchbaren Call-Stack-Baum einpackt, der mit der Zeit oder dem Speicher für jede Funktion, entweder kumulativ oder pro Funktion.




Related