¿Qué hace pprof -call_tree?
go tool pprof
tiene una opción -call_tree
que, según -help
, debería “Crear un árbol de llamadas sensible al contexto”. Sin embargo, pprof -tree
en un perfil de CPU me da la misma salida exacta con y sin esta opción. Se ve así (un nodo representativo):
flat flat% sum% cum cum% calls calls% + context
----------------------------------------------------------+-------------
0.07s 35.00% | google.golang.org/grpc/internal/transport.(http2Server).operateHeaders
0.04s 20.00% | golang.org/x/net/http2.(Framer).readMetaFrame
0.02s 10.00% | github.com/Shopify/sarama.(*FetchResponse).decode
0.06s 0.79% 51.18% 0.20s 2.63% | runtime.mapassign_faststr
0.05s 25.00% | runtime.newobject (inline)
0.03s 15.00% | aeshashbody
0.03s 15.00% | runtime.mallocgc
Esto claramente no es un árbol, no menos importante porque muestra a Sarama bajo HTTP/2: consumir de Kafka (a través de Sarama) y servir HTTP/2 son dos cosas independientes que este proceso hace concurrentemente.
¿Por qué -call_tree
no afecta esta salida de -tree
? En general, ¿qué hace -call_tree
?
Puntos extra
¿Cuál es el significado exacto del nodo de salida que mostré arriba? ¿Significa que el 35% de las muestras que contienen mapassign_faststr
también contienen operateHeaders
en algún lugar de la pila, y el 10% contiene decode
? ¿Qué pasa con las líneas siguientes, como mallocgc
?
¿Qué documentos podría leer para responder a las preguntas anteriores?
davy.ai
Comprendiendo la opción
-call_tree
engo tool pprof
La opción
-call_tree
engo tool pprof
se supone que crea un árbol de llamadas contextual. Sin embargo, al utilizar el comando-tree
para ver el perfil de la CPU, el uso de-call_tree
no parece afectar la salida. La salida sigue apareciendo como un perfil plano, mostrando el porcentaje de tiempo invertido en cada función y su pila de llamadas.Entonces, ¿qué hace
-call_tree
? Según la documentación oficial,-call_tree
crea un árbol de llamadas contextual, teniendo en cuenta el contexto de la pila de cada muestra. Esto significa que cada nodo en el árbol representa una secuencia de llamadas, no solo una llamada de función única. La etiqueta de cada nodo muestra el camino de llamada exacto, incluyendo todas las funciones desde la raíz hasta la función actual.Sin embargo, esta opción solo funciona para perfiles generados por
go test
ygo benchmark
. No funciona para perfiles generados porgo tool pprof
en sí mismo. Esto es probablemente por qué no estamos viendo ninguna diferencia en la salida al usar-call_tree
con-tree
.Crédito Extra
El nodo de salida mostrado arriba representa la función
http2Server.operateHeaders
en el paquetegoogle.golang.org/grpc/internal/transport
. Muestra que esta función fue responsable del 35% del tiempo de CPU en el perfil y fue llamada por la función raíz. Además, muestra que el 20% del tiempo de CPU se invirtió en la funciónFramer.readMetaFrame
del paquetegolang.org/x/net/http2
, y otro 10% se invirtió en la funciónFetchResponse.decode
del paquetegithub.com/Shopify/sarama
.Las otras líneas en la salida representan otras funciones que fueron llamadas por la función
operateHeaders
. Por ejemplo,mapassign_faststr
fue llamada por algunas de las funciones más abajo en la pila de llamadas.Para aprender más sobre la interpretación de perfiles de CPU generados por
go tool pprof
, la documentación oficial de Go es un buen lugar para comenzar. Además, el comandogo tool pprof
tiene una documentación de ayuda incorporada con explicaciones de todas las opciones disponibles.