Dies ist ein Python-Skript zum Konvertieren der Ausgabe vieler Profiler in ein Punktdiagramm.
Es kann:
Wenn Sie einen interaktiven Viewer für die von gprof2dot generierten Diagramme wünschen, überprüfen Sie xdot.py.
gprof2dot erfüllt derzeit meine Anforderungen und ich habe wenig oder gar keine Zeit für die Wartung. Daher befürchte ich, dass die angeforderten Funktionen wahrscheinlich nicht implementiert werden und ich möglicherweise langsame Problemberichte oder Pull-Anfragen verarbeite.
Dies ist das Ergebnis der Beispieldaten im Linux Gazette-Artikel mit den Standardeinstellungen:
Auf Debian/Ubuntu ausgeführt:
apt-get install python3 graphviz
Auf RedHat/Fedora-Lauf
yum install python3 graphviz
PyPI
pip install gprof2dot
Eigenständiges Skript
Git-Repository
Usage:
gprof2dot.py [options] [file] ...
Options:
-h, --help show this help message and exit
-o FILE, --output=FILE
output filename [stdout]
-n PERCENTAGE, --node-thres=PERCENTAGE
eliminate nodes below this threshold [default: 0.5]
-e PERCENTAGE, --edge-thres=PERCENTAGE
eliminate edges below this threshold [default: 0.1]
-f FORMAT, --format=FORMAT
profile format: axe, callgrind, collapse, dtrace,
hprof, json, oprofile, perf, prof, pstats, sleepy,
sysprof or xperf [default: prof]
--total=TOTALMETHOD preferred method of calculating total time: callratios
or callstacks (currently affects only perf format)
[default: callratios]
-c THEME, --colormap=THEME
color map: bw, color, gray, pink or print [default:
color]
-s, --strip strip function parameters, template parameters, and
const modifiers from demangled C++ function names
--color-nodes-by-selftime
color nodes by self time, rather than by total time
(sum of self and descendants)
-w, --wrap wrap function names
--show-samples show function samples
--node-label=MEASURE measurements to on show the node (can be specified
multiple times): self-time, self-time-percentage,
total-time or total-time-percentage [default: total-
time-percentage, self-time-percentage]
--list-functions=LIST_FUNCTIONS
list functions available for selection in -z or -l,
requires selector argument ( use '+' to select all).
Recall that the selector argument is used with
Unix/Bash globbing/pattern matching, and that entries
are formatted '::'. When
argument starts with '%', a dump of all available
information is performed for selected entries, after
removal of leading '%'.
-z ROOT, --root=ROOT prune call graph to show only descendants of specified
root function
-l LEAF, --leaf=LEAF prune call graph to show only ancestors of specified
leaf function
--depth=DEPTH prune call graph to show only descendants or ancestors
until specified depth
--skew=THEME_SKEW skew the colorization curve. Values < 1.0 give more
variety to lower percentages. Values > 1.0 give less
variety to lower percentages
-p FILTER_PATHS, --path=FILTER_PATHS
Filter all modules not in a specified path
--compare Compare two graphs with almost identical structure. With this
option two files should be provided.gprof2dot.py
[options] --compare [file1] [file2] ...
--compare-tolerance=TOLERANCE
Tolerance threshold for node difference
(default=0.001%).If the difference is below this value
the nodes are considered identical.
--compare-only-slower
Display comparison only for function which are slower
in second graph.
--compare-only-faster
Display comparison only for function which are faster
in second graph.
--compare-color-by-difference
Color nodes based on the value of the difference.
Nodes with the largest differences represent the hot
spots.
perf record -g -- /path/to/your/executable
perf script | c++filt | gprof2dot.py -f perf | dot -Tpng -o output.png
opcontrol --callgraph=16
opcontrol --start
/path/to/your/executable arg1 arg2
opcontrol --stop
opcontrol --dump
opreport -cgf | gprof2dot.py -f oprofile | dot -Tpng -o output.png
Wenn Sie mit xperf nicht vertraut sind, lesen Sie zuerst diesen hervorragenden Artikel. Dann tun Sie:
Starten Sie xperf als
xperf -on Latency -stackwalk profile
Führen Sie Ihre Anwendung aus.
Speichern Sie die Daten. ` xperf -d Ausgabe.etl
Starten Sie den Visualizer:
xperf output.etl
Wählen Sie im Menü „Trace “ die Option „Symbole laden“ aus. Konfigurieren Sie bei Bedarf Symbolpfade .
Wählen Sie im CPU-Stichprobendiagramm einen Bereich von Interesse aus, klicken Sie mit der rechten Maustaste und wählen Sie Übersichtstabelle aus.
Stellen Sie im Menü „Spalten“ sicher, dass die Spalte „ Stapel “ aktiviert und sichtbar ist.
Klicken Sie mit der rechten Maustaste auf eine Zeile, wählen Sie „Vollständige Tabelle exportieren“ und speichern Sie sie in „output.csv“ .
Rufen Sie dann gprof2dot als auf
gprof2dot.py -f xperf output.csv | dot -Tpng -o output.png
Sammeln Sie Profildaten wie folgt (kann auch über die GUI erfolgen):
amplxe-cl -collect hotspots -result-dir output -- your-app
Visualisieren Sie Profildaten als:
amplxe-cl -report gprof-cc -result-dir output -format text -report-output output.txt
gprof2dot.py -f axe output.txt | dot -Tpng -o output.png
Siehe auch den Blogbeitrag von Kirill Rogozhin.
/path/to/your/executable arg1 arg2
gprof path/to/your/executable | gprof2dot.py | dot -Tpng -o output.png
python -m profile -o output.pstats path/to/your/script arg1 arg2
gprof2dot.py -f pstats output.pstats | dot -Tpng -o output.png
python -m cProfile -o output.pstats path/to/your/script arg1 arg2
gprof2dot.py -f pstats output.pstats | dot -Tpng -o output.png
java -agentlib:hprof=cpu=samples ...
gprof2dot.py -f hprof java.hprof.txt | dot -Tpng -o output.png
Weitere Informationen finden Sie im Blogbeitrag von Russell Power.
dtrace -x ustackframes=100 -n 'profile-97 /pid == 12345/ { @[ustack()] = count(); } tick-60s { exit(0); }' -o out.user_stacks
gprof2dot.py -f dtrace out.user_stacks | dot -Tpng -o output.png
# Notice: sometimes, the dtrace outputs format may be latin-1, and gprof2dot will fail to parse it.
# To solve this problem, you should use iconv to convert to UTF-8 explicitly.
# TODO: add an encoding flag to tell gprof2dot how to decode the profile file.
iconv -f ISO-8859-1 -t UTF-8 out.user_stacks | gprof2dot.py -f dtrace
Das FlameGraph-Tool von Brendan Gregg verwendet als Eingabe eine Textdatei, die eine Zeile pro Beispiel enthält. Dieses Format kann aus verschiedenen anderen Eingaben mithilfe der stackcollapse
Skripte im FlameGraph-Repository generiert werden. Es kann auch von Tools wie Py-Spy generiert werden.
Beispielverwendung:
Perf
perf record -g -- /path/to/your/executable
perf script | FlameGraph/stackcollapse-perf.pl > out.collapse
gprof2dot.py -f collapse out.collapse | dot -Tpng -o output.png
Py-Spion
py-spy record -p -f raw -o out.collapse
gprof2dot.py -f collapse out.collapse | dot -Tpng -o output.png
Dieses Bild zeigt ein Beispiel für die Verwendung der Optionen --compare
und --compare-color-by-difference
.
Nach rechts zeigende Pfeile zeigen Knoten an, bei denen die Funktion in dem als zweites bereitgestellten Profil (zweites Profil) schneller ausgeführt wurde, während nach links zeigende Pfeile Knoten anzeigen, bei denen die Funktion in dem als erstes bereitgestellten Profil (erstes Profil) schneller ausgeführt wurde. .
+-----------------------------+
| function name
| total time % -/+ total_diff
| ( self time % ) -/+ self_diff /
| total calls1 / total calls2 /
+-----------------------------+
Wo
total time %
und self time %
stammen aus dem ersten Profildiff
wird als absoluter Wert der time in the first profile - time in the second profile
berechnet.Hinweis: Die Vergleichsoption wurde für pstats-, ax- und callgrind-Profile getestet.
Ein Knoten im Ausgabediagramm stellt eine Funktion dar und hat das folgende Layout:
+------------------------------+
| function name |
| total time % ( self time % ) |
| total calls |
+------------------------------+
Wo:
Eine Kante stellt die Aufrufe zwischen zwei Funktionen dar und hat folgenden Aufbau:
total time %
calls
parent --------------------> children
Wo:
Beachten Sie, dass in rekursiven Zyklen die Gesamtzeit % im Knoten für alle Funktionen im Zyklus gleich ist und es an den Kanten innerhalb des Zyklus keine Gesamtzeit % gibt, da eine solche Zahl keinen Sinn ergeben würde.
Die Farbe der Knoten und Kanten variiert je nach Gesamtzeit-%- Wert. In der standardmäßigen temperaturähnlichen Farbkarte werden Funktionen, bei denen die meiste Zeit aufgewendet wird (Hotspots), als gesättigtes Rot markiert, und Funktionen, bei denen wenig Zeit aufgewendet wird, werden als dunkelblau markiert. Beachten Sie, dass Funktionen, für die nur vernachlässigbare oder gar keine Zeit aufgewendet wird, standardmäßig nicht im Diagramm angezeigt werden.
Das Flag --list-functions
ermöglicht das Auflisten der in der gprof
Eingabe gefundenen Funktionseinträge. Dies ist als Werkzeug zur Vorbereitung auf Nutzungen mit den Flags --leaf
( -l
) oder --root
( -z
) gedacht.
prof2dot.py -f pstats /tmp/myLog.profile --list-functions "test_segments:*:*"
test_segments:5:,
test_segments:206:TestSegments,
test_segments:46:
Das Argument „Selektor“ wird beim Unix/Bash-Globbing/Mustervergleich auf die gleiche Weise verwendet wie bei den Flags -l
und -z
.
Einträge haben das Format „
Wenn das Selektorargument mit „%“ beginnt, wird ein Dump aller verfügbaren Informationen für ausgewählte Einträge durchgeführt, nachdem das führende „%“ des Selektors entfernt wurde. Wenn der Selektor „+“ oder „*“ ist, wird die vollständige Liste der Funktionen gedruckt.
Standardmäßig generiert gprof2dot.py
einen partiellen Aufrufgraphen, der Knoten und Kanten ausschließt und nur geringe oder keine Auswirkungen auf die Gesamtrechenzeit hat. Wenn Sie das vollständige Aufrufdiagramm wünschen, legen Sie über die Optionen -n
/ --node-thres
und -e
/ --edge-thres
einen Nullschwellenwert für Knoten und Kanten fest, wie folgt:
gprof2dot.py -n0 -e0
Die Knotenbezeichnungen können bei der Profilerstellung von C++-Code aufgrund der Einbeziehung von Bereich, Funktionsargumenten und Vorlagenargumenten in entschlüsselte C++-Funktionsnamen sehr breit werden.
Wenn Sie keine Informationen zu Funktions- und Vorlagenargumenten benötigen, übergeben Sie die Option -s
/ --strip
um diese zu entfernen.
Wenn Sie alle diese Informationen behalten möchten oder die Beschriftungen immer noch zu breit sind, können Sie -w
/ --wrap
übergeben, um die Beschriftungen zu umbrechen. Beachten Sie, dass die Etikettenränder nicht perfekt ausgerichtet sind, da dot
Etiketten nicht automatisch umbricht.
Wahrscheinlich ist die Gesamtausführungszeit zu kurz, sodass das Profil nicht genau genug ist, um zu bestimmen, wo Zeit aufgewendet wird.
Sie können dennoch die Anzeige des gesamten Diagramms erzwingen, indem Sie über die Optionen -n
/ --node-thres
und -e
/ --edge-thres
einen Schwellenwert von Null für Knoten und Kanten festlegen:
gprof2dot.py -n0 -e0
Um jedoch aussagekräftige Ergebnisse zu erhalten, müssen Sie eine Möglichkeit finden, das Programm über einen längeren Zeitraum auszuführen (Ergebnisse aus mehreren Läufen aggregieren).
Wahrscheinlich ist die Ausführungszeit zu kurz, was zu großen Rundungsfehlern führt.
In der Frage oben finden Sie Möglichkeiten, die Ausführungszeit zu verlängern.
Folgende Optionen sind für die Erzielung geeigneter Ergebnisse unerlässlich :
-g
: Debugging-Informationen erzeugen-fno-omit-frame-pointer
: Verwenden Sie den Frame-Zeiger (die Verwendung des Frame-Zeigers ist in einigen Architekturen wie x86_64 und für einige Optimierungsstufen standardmäßig deaktiviert; es ist unmöglich, den Aufrufstapel ohne ihn zu durchlaufen) Wenn Sie gprof verwenden, benötigen Sie auch die Option -pg
, aber heutzutage können Sie mit anderen Profiling-Tools viel bessere Ergebnisse erzielen, von denen die meisten beim Kompilieren keine spezielle Code-Instrumentierung erfordern.
Sie möchten, dass der Code, den Sie profilieren, so nah wie möglich an dem Code ist, den Sie veröffentlichen werden. Daher sollten Sie alle Optionen, die Sie verwenden, in Ihren Release-Code einbeziehen, normalerweise:
-O2
: Optimierungen, die keinen Kompromiss hinsichtlich der Raumgeschwindigkeit beinhalten-DNDEBUG
: Debugging-Code in der Standardbibliothek deaktivieren (z. B. das Assert-Makro)Viele der von gcc durchgeführten Optimierungen beeinträchtigen jedoch die Genauigkeit/Granularität der Profilerstellungsergebnisse. Sie sollten diese Optionen übergeben, um diese speziellen Optimierungen zu deaktivieren:
-fno-inline-functions
: Integrieren Sie keine Funktionen in ihre übergeordneten Funktionen (andernfalls wird die für diese Funktionen aufgewendete Zeit dem Aufrufer zugeschrieben).-fno-inline-functions-called-once
: ähnlich wie oben-fno-optimize-sibling-calls
: Geschwister- und Tail-rekursive Aufrufe werden nicht optimiert (andernfalls könnten Tail-Aufrufe der übergeordneten Funktion zugeordnet werden).Wenn die Granularität immer noch zu niedrig ist, können Sie diese Optionen übergeben, um eine feinere Granularität zu erreichen:
-fno-default-inline
: Mitgliedsfunktionen nicht standardmäßig inline machen, nur weil sie innerhalb des Klassenbereichs definiert sind-fno-inline
: Achten Sie nicht auf das Inline-Schlüsselwort. Beachten Sie jedoch, dass bei diesen letzten Optionen das Timing von Funktionen, die häufig aufgerufen werden, aufgrund des Funktionsaufruf-Overheads verzerrt wird. Dies gilt insbesondere für typischen C++-Code, der erwartet , dass diese Optimierungen für eine angemessene Leistung durchgeführt werden.Weitere Informationen finden Sie in der vollständigen Liste der gcc-Optimierungsoptionen.
Im Wiki finden Sie externe Ressourcen, einschließlich ergänzender/alternativer Tools.