Este es un script de Python para convertir la salida de muchos generadores de perfiles en un gráfico de puntos.
Puede:
Si desea un visor interactivo para los gráficos generados por gprof2dot , consulte xdot.py.
Actualmente gprof2dot satisface mis necesidades y tengo poco o ningún tiempo para su mantenimiento. Por lo tanto, me temo que es poco probable que se implementen las funciones solicitadas y que podría tardar en procesar los informes de problemas o las solicitudes de extracción.
Este es el resultado de los datos de ejemplo en el artículo de Linux Gazette con la configuración predeterminada:
En Debian/Ubuntu ejecute:
apt-get install python3 graphviz
En ejecución RedHat/Fedora
yum install python3 graphviz
PyPI
pip install gprof2dot
Guión independiente
repositorio 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 no está familiarizado con xperf, lea primero este excelente artículo. Entonces haz:
Iniciar xperf como
xperf -on Latency -stackwalk profile
Ejecute su aplicación.
Guarde los datos. ` xperf -d salida.etl
Inicie el visualizador:
xperf output.etl
En el menú Trazar , seleccione Cargar símbolos . Configure rutas de símbolos si es necesario.
Seleccione un área de interés en el gráfico de muestreo de CPU , haga clic derecho y seleccione Tabla de resumen .
En el menú Columnas , asegúrese de que la columna Pila esté habilitada y visible.
Haga clic derecho en una fila, elija Exportar tabla completa y guárdela en salida.csv .
Luego invoca gprof2dot como
gprof2dot.py -f xperf output.csv | dot -Tpng -o output.png
Recopile datos de perfil como (también se puede hacer desde la GUI):
amplxe-cl -collect hotspots -result-dir output -- your-app
Visualice los datos del perfil como:
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
Véase también la entrada del 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
Consulte la publicación del blog de Russell Power para obtener más detalles.
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
La herramienta FlameGraph de Brendan Gregg toma como entrada un archivo de texto que contiene una línea por muestra. Este formato se puede generar a partir de otras entradas utilizando los scripts stackcollapse
en el repositorio de FlameGraph. También puede ser generado por herramientas como py-spy.
Uso de ejemplo:
rendimiento
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-espía
py-spy record -p -f raw -o out.collapse
gprof2dot.py -f collapse out.collapse | dot -Tpng -o output.png
Esta imagen ilustra un ejemplo de uso de las opciones --compare
y --compare-color-by-difference
.
La flecha que apunta hacia la derecha indica el nodo donde la función se realizó más rápido en el perfil proporcionado como segundo (segundo perfil), mientras que la flecha que apunta hacia la izquierda indica el nodo donde la función fue más rápida en el perfil proporcionado como primero (primer perfil) .
+-----------------------------+
| function name
| total time % -/+ total_diff
| ( self time % ) -/+ self_diff /
| total calls1 / total calls2 /
+-----------------------------+
Dónde
total time %
y self time %
provienen del primer perfil.diff
se calcula como el valor absoluto del time in the first profile - time in the second profile
.Nota La opción de comparación ha sido probada para los perfiles pstats, ax y callgrind.
Un nodo en el gráfico de salida representa una función y tiene el siguiente diseño:
+------------------------------+
| function name |
| total time % ( self time % ) |
| total calls |
+------------------------------+
dónde:
Un borde representa las llamadas entre dos funciones y tiene el siguiente diseño:
total time %
calls
parent --------------------> children
Dónde:
Tenga en cuenta que en los ciclos recursivos, el % de tiempo total en el nodo es el mismo para todas las funciones del ciclo, y no hay una cifra de % de tiempo total en los bordes dentro del ciclo, ya que dicha cifra no tendría sentido.
El color de los nodos y bordes varía según el valor del % de tiempo total . En el mapa de colores predeterminado similar a la temperatura , las funciones en las que se dedica la mayor parte del tiempo (puntos calientes) están marcadas en rojo saturado, y las funciones en las que se dedica poco tiempo están marcadas en azul oscuro. Tenga en cuenta que las funciones en las que se dedica poco o ningún tiempo no aparecen en el gráfico de forma predeterminada.
La bandera --list-functions
permite enumerar las entradas de funciones que se encuentran en la entrada gprof
. Esto está pensado como una herramienta para prepararse para las utilizaciones con los indicadores --leaf
( -l
) o --root
( -z
).
prof2dot.py -f pstats /tmp/myLog.profile --list-functions "test_segments:*:*"
test_segments:5:,
test_segments:206:TestSegments,
test_segments:46:
El argumento selector se utiliza con la coincidencia de patrones/globbing de Unix/Bash, de la misma manera que lo realizan los indicadores -l
y -z
.
Las entradas tienen el formato '
Cuando el argumento del selector comienza con '%', se realiza un volcado de toda la información disponible para las entradas seleccionadas, después de eliminar el '%' inicial del selector. Si el selector es "+" o "*", se imprime la lista completa de funciones.
De forma predeterminada, gprof2dot.py
genera un gráfico de llamadas parcial , excluyendo nodos y bordes con poco o ningún impacto en el tiempo total de cálculo. Si desea el gráfico de llamadas completo, establezca un umbral cero para nodos y bordes mediante las opciones -n
/ --node-thres
y -e
/ --edge-thres
, como:
gprof2dot.py -n0 -e0
Las etiquetas de los nodos pueden volverse muy amplias al crear perfiles de código C++, debido a la inclusión de alcance, argumentos de función y argumentos de plantilla en los nombres de funciones de C++ demandados.
Si no necesita información sobre los argumentos de la función y la plantilla, pase la opción -s
/ --strip
para eliminarlos.
Si desea conservar toda esa información, o si las etiquetas aún son demasiado anchas, puede pasar -w
/ --wrap
para ajustar las etiquetas. Tenga en cuenta que debido a que dot
no ajusta las etiquetas automáticamente, los márgenes de las etiquetas no estarán perfectamente alineados.
Probablemente, el tiempo total de ejecución sea demasiado corto, por lo que no hay suficiente precisión en el perfil para determinar dónde se está invirtiendo el tiempo.
Aún puedes forzar la visualización del gráfico completo estableciendo un umbral cero para nodos y bordes mediante las opciones -n
/ --node-thres
y -e
/ --edge-thres
, como:
gprof2dot.py -n0 -e0
Pero para obtener resultados significativos necesitará encontrar una manera de ejecutar el programa durante un período de tiempo más largo (resultados agregados de múltiples ejecuciones).
Es probable que el tiempo de ejecución sea demasiado corto, lo que provoca que los errores de redondeo sean grandes.
Consulte la pregunta anterior para conocer formas de aumentar el tiempo de ejecución.
Las opciones que son esenciales para producir resultados adecuados son:
-g
: produce información de depuración-fno-omit-frame-pointer
: usa el puntero de marco (el uso del puntero de marco está deshabilitado de forma predeterminada en algunas arquitecturas como x86_64 y para algunos niveles de optimización; es imposible recorrer la pila de llamadas sin él) Si está utilizando gprof, también necesitará la opción -pg
, pero hoy en día puede obtener resultados mucho mejores con otras herramientas de creación de perfiles, la mayoría de las cuales no requieren instrumentación de código especial al compilar.
Quiere que el código que está perfilando sea lo más parecido posible al código que publicará. Por lo tanto, debes incluir todas las opciones que utilizas en tu código de lanzamiento, normalmente:
-O2
: optimizaciones que no implican un equilibrio entre velocidad espacial-DNDEBUG
: deshabilita el código de depuración en la biblioteca estándar (como la macro de afirmación)Sin embargo, muchas de las optimizaciones realizadas por gcc interfieren con la precisión/granularidad de los resultados de la creación de perfiles. Debe pasar estas opciones para deshabilitar esas optimizaciones particulares:
-fno-inline-functions
: no integra funciones en sus padres (de lo contrario, el tiempo dedicado a estas funciones se atribuirá a la persona que llama)-fno-inline-functions-called-once
: similar a lo anterior-fno-optimize-sibling-calls
: no optimiza las llamadas recursivas entre hermanos y de cola (de lo contrario, las llamadas de cola pueden atribuirse a la función principal)Si la granularidad aún es demasiado baja, puede pasar estas opciones para lograr una granularidad más fina:
-fno-default-inline
: no haga que las funciones miembro estén en línea de forma predeterminada simplemente porque están definidas dentro del alcance de la clase-fno-inline
: no preste atención a la palabra clave en línea. Sin embargo, tenga en cuenta que con estas últimas opciones los tiempos de las funciones llamadas muchas veces se distorsionarán debido a la sobrecarga de la llamada a la función. Esto es particularmente cierto para el código C++ típico que espera que estas optimizaciones se realicen para lograr un rendimiento decente.Consulte la lista completa de opciones de optimización de gcc para obtener más información.
Consulte la wiki para obtener recursos externos, incluidas herramientas complementarias/alternativas.