Il s'agit d'un script Python permettant de convertir la sortie de nombreux profileurs en un graphique à points.
Ça peut:
Si vous souhaitez une visionneuse interactive pour les graphiques générés par gprof2dot , consultez xdot.py.
gprof2dot répond actuellement à mes besoins, et j'ai peu ou pas de temps pour sa maintenance. J'ai donc peur qu'il soit peu probable que les fonctionnalités demandées soient implémentées, et je pourrais être lent à traiter les rapports de problèmes ou les demandes d'extraction.
Voici le résultat des exemples de données de l'article de la Linux Gazette avec les paramètres par défaut :
Sous Debian/Ubuntu :
apt-get install python3 graphviz
Sur RedHat/Fedora
yum install python3 graphviz
PyPI
pip install gprof2dot
Script autonome
Dépôt Git
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
Si vous n'êtes pas familier avec xperf, lisez d'abord cet excellent article. Faites ensuite :
Démarrez xperf en tant que
xperf -on Latency -stackwalk profile
Exécutez votre application.
Enregistrez les données. ` xperf -d sortie.etl
Démarrez le visualiseur :
xperf output.etl
Dans le menu Trace , sélectionnez Charger les symboles . Configurez les chemins de symboles si nécessaire.
Sélectionnez une zone d'intérêt sur le graphique d'échantillonnage du processeur , cliquez avec le bouton droit et sélectionnez Tableau récapitulatif .
Dans le menu Colonnes , assurez-vous que la colonne Pile est activée et visible.
Faites un clic droit sur une ligne, choisissez Export Full Table et enregistrez dans output.csv .
Ensuite, appelez gprof2dot comme
gprof2dot.py -f xperf output.csv | dot -Tpng -o output.png
Collectez les données de profil comme (peut également être fait à partir de l'interface graphique) :
amplxe-cl -collect hotspots -result-dir output -- your-app
Visualisez les données de profil comme :
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
Voir aussi le billet de blog de 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
Voir le billet de blog de Russell Power pour plus de détails.
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
L'outil FlameGraph de Brendan Gregg prend en entrée un fichier texte contenant une ligne par échantillon. Ce format peut être généré à partir de diverses autres entrées à l'aide des scripts stackcollapse
du référentiel FlameGraph. Il peut également être généré par des outils tels que py-spy.
Exemple d'utilisation :
Performance
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-espion
py-spy record -p -f raw -o out.collapse
gprof2dot.py -f collapse out.collapse | dot -Tpng -o output.png
Cette image illustre un exemple d'utilisation des options --compare
et --compare-color-by-difference
.
La flèche pointant vers la droite indique le nœud où la fonction était exécutée plus rapidement dans le profil fourni comme deuxième (deuxième profil), tandis que la flèche pointant vers la gauche indique le nœud où la fonction était plus rapide dans le profil fourni comme premier (premier profil). .
+-----------------------------+
| function name
| total time % -/+ total_diff
| ( self time % ) -/+ self_diff /
| total calls1 / total calls2 /
+-----------------------------+
Où
total time %
et self time %
proviennent du premier profildiff
est calculé comme la valeur absolue du time in the first profile - time in the second profile
.Remarque L'option de comparaison a été testée pour les profils pstats, ax et callgrind.
Un nœud dans le graphique de sortie représente une fonction et a la disposition suivante :
+------------------------------+
| function name |
| total time % ( self time % ) |
| total calls |
+------------------------------+
où:
Une arête représente les appels entre deux fonctions et a la disposition suivante :
total time %
calls
parent --------------------> children
Où:
Notez que dans les cycles récursifs, le pourcentage de temps total dans le nœud est le même pour toutes les fonctions du cycle, et il n'y a pas de pourcentage de temps total sur les bords à l'intérieur du cycle, car un tel chiffre n'aurait aucun sens.
La couleur des nœuds et des bords varie en fonction de la valeur du pourcentage de temps total . Dans la carte de couleurs par défaut, semblable à la température , les fonctions sur lesquelles on passe le plus de temps (points chauds) sont marquées en rouge saturé, et les fonctions sur lesquelles on passe peu de temps sont marquées en bleu foncé. Notez que les fonctions pour lesquelles un temps négligeable ou nul est consacré n'apparaissent pas dans le graphique par défaut.
Le flag --list-functions
permet de lister les entrées de fonctions trouvées dans l'entrée gprof
. Ceci est destiné à être un outil pour préparer les utilisations avec les indicateurs --leaf
( -l
) ou --root
( -z
).
prof2dot.py -f pstats /tmp/myLog.profile --list-functions "test_segments:*:*"
test_segments:5:,
test_segments:206:TestSegments,
test_segments:46:
L'argument sélecteur est utilisé avec la globalisation/correspondance de modèles Unix/Bash, de la même manière que celle effectuée par les indicateurs -l
et -z
.
Les entrées sont au format '
Lorsque l'argument du sélecteur commence par « % », un vidage de toutes les informations disponibles est effectué pour les entrées sélectionnées, après suppression du « % » initial du sélecteur. Si le sélecteur est "+" ou "*", la liste complète des fonctions est imprimée.
Par défaut, gprof2dot.py
génère un graphe d'appel partiel , excluant les nœuds et les arêtes avec peu ou pas d'impact sur le temps total de calcul. Si vous souhaitez le graphique d'appel complet, définissez un seuil zéro pour les nœuds et les arêtes via les options -n
/ --node-thres
et -e
/ --edge-thres
, comme :
gprof2dot.py -n0 -e0
Les étiquettes de nœuds peuvent devenir très larges lors du profilage du code C++, en raison de l'inclusion de la portée, des arguments de fonction et des arguments de modèle dans les noms de fonctions C++ démêlés.
Si vous n'avez pas besoin d'informations sur les arguments de fonction et de modèle, passez l'option -s
/ --strip
pour les supprimer.
Si vous souhaitez conserver toutes ces informations, ou si les étiquettes sont encore trop larges, alors vous pouvez passer le -w
/ --wrap
, pour envelopper les étiquettes. Notez que, comme dot
n'enveloppe pas automatiquement les étiquettes, les marges de l'étiquette ne seront pas parfaitement alignées.
Il est probable que le temps d'exécution total soit trop court et qu'il n'y ait donc pas assez de précision dans le profil pour déterminer où le temps est passé.
Vous pouvez toujours forcer l'affichage de l'intégralité du graphique en définissant un seuil zéro pour les nœuds et les arêtes via les options -n
/ --node-thres
et -e
/ --edge-thres
, comme :
gprof2dot.py -n0 -e0
Mais pour obtenir des résultats significatifs, vous devrez trouver un moyen d’exécuter le programme sur une période plus longue (résultats agrégés de plusieurs exécutions).
Votre temps d'exécution est probablement trop court, ce qui entraîne des erreurs d'arrondi importantes.
Voir la question ci-dessus pour savoir comment augmenter le temps d'exécution.
Les options essentielles pour produire des résultats appropriés sont :
-g
: produit des informations de débogage-fno-omit-frame-pointer
: utilise le pointeur de trame (l'utilisation du pointeur de trame est désactivée par défaut dans certaines architectures comme x86_64 et pour certains niveaux d'optimisation ; il est impossible de parcourir la pile d'appels sans lui) Si vous utilisez gprof, vous aurez également besoin de l'option -pg
, mais de nos jours, vous pouvez obtenir de bien meilleurs résultats avec d'autres outils de profilage, dont la plupart ne nécessitent aucune instrumentation de code spéciale lors de la compilation.
Vous souhaitez que le code que vous profilez soit aussi proche que possible du code que vous allez publier. Vous devez donc inclure toutes les options que vous utilisez dans votre code de version, généralement :
-O2
: optimisations qui n'impliquent pas de compromis espace-vitesse-DNDEBUG
: désactive le code de débogage dans la bibliothèque standard (comme la macro assert)Cependant, de nombreuses optimisations effectuées par gcc interfèrent avec la précision/granularité des résultats de profilage. Vous devez transmettre ces options pour désactiver ces optimisations particulières :
-fno-inline-functions
: n'inline pas les fonctions dans leurs parents (sinon le temps passé sur ces fonctions sera attribué à l'appelant)-fno-inline-functions-called-once
: similaire à ci-dessus-fno-optimize-sibling-calls
: n'optimise pas les appels récursifs frères et sœurs (sinon les appels tail peuvent être attribués à la fonction parent)Si la granularité est encore trop faible, vous pouvez ignorer ces options pour obtenir une granularité plus fine :
-fno-default-inline
: ne rend pas les fonctions membres en ligne par défaut simplement parce qu'elles sont définies dans la portée de la classe-fno-inline
: ne faites pas attention au mot-clé inline. Notez cependant qu'avec ces dernières options, les timings des fonctions appelées plusieurs fois seront faussés en raison de la surcharge de l'appel de fonction. Cela est particulièrement vrai pour le code C++ typique qui s'attend à ce que ces optimisations soient effectuées pour des performances décentes.Consultez la liste complète des options d'optimisation de gcc pour plus d'informations.
Consultez le wiki pour les ressources externes, y compris les outils complémentaires/alternatifs.