LINUX

Cómo usar la herramienta de creación de perfiles Gprof en Linux (tutorial)

A medida que el código crece, también aumenta el número de funciones y las llamadas a funciones anidadas. Por lo tanto, para analizar el rendimiento de un programa de este tipo, es necesario comprender qué funciones tardan en ejecutarse. Asimismo, el análisis de la función individual también debe proporcionar una distinción clara entre el tiempo que tarda la función principal y las otras funciones llamadas dentro de la función principal.

Las herramientas de software que se utilizan para este tipo de análisis de rendimiento se conocen popularmente como perfiladores. En este tutorial, analizaremos un generador de perfiles basado en Linux llamado gprof.

Todos los ejemplos presentados en este artículo se prueban en Ubuntu, bash 4.2.45 y gprof 2.23.2.

Configurando y usando Gprof

Estos son algunos de los pasos necesarios para descargar y configurar un entorno para gprof:

  • Si aún no está instalado, descargue e instale gprof ejecutando «apt-get install binutils».
  • Para verificar si gprof está instalado correctamente, ejecute el comando gprof y debería dar un error como «a.out: No existe tal archivo o directorio».
  • Suponiendo que el compilador use gcc o cc, compile su código con la opción «-pg» para que el ejecutable incluya código adicional para fines de generación de perfiles.
  • Ejecute el programa de forma normal. Cuando finalice el programa, se generará un archivo llamado «gmon.out» (datos de perfil) en el mismo directorio desde el que se ejecutó el programa.
  • Utilice el generador de perfiles gprof para procesar estos datos del generador de perfiles (gmon.out) y producir análisis de rendimiento legibles por humanos y estadísticas del programa.

Aquí hay un ejemplo del código que queremos perfilar:

#include<stdio.h>

void some_other_test(void)
{
printf("n Inside the function some_other_test() n");
int i = 0;
for(;i<=0XFFFF;i++);
}

void yet_another_test(void)
{
printf("n Inside the function yet_other_test() n");
int i = 0;
for(;i<=0XFFFFFFF;i++);
}

void another_test(void)
{
printf("n Inside the function another_test() n");
int i = 0;
for(;i<=0XFFF;i++);

yet_another_test();
}

void test(void)
{
printf("n Inside the function test() n");
int i = 0;
for(;i<=0XFFFFFF;i++);

another_test();
}

int main(void)
{
printf("n Inside the function main() n");
int i = 0;
for(;i<=0XFFFFF;i++);

test();
some_other_test();

return 0;
}

Tenga en cuenta que el código anterior es solo un ejemplo simulado que contiene bucles for para simular el consumo de tiempo en el procesamiento de la función.

Una vez que se ingresa el código, el primer paso es compilar el código. Así es como puedes hacerlo:

$ gcc -Wall -pg profile.c -o profile

Entonces puede ver que el código se guardó en un archivo llamado «perfil.c» y el nombre del archivo de salida es «perfil».

Una vez que se produjo el ejecutable llamado «perfil», se ejecutó como cualquier otro programa:

$ ./profile

Inside the function main()

Inside the function test()

Inside the function another_test()

Inside the function yet_other_test()

Inside the function some_other_test()

Entonces puede ver que el programa se ejecutó con éxito. También produjo un archivo llamado «gmon.out» en el mismo directorio.

$ ls gmon.out
gmon.out

Ahora use la utilidad gprof de la siguiente manera:

$ gprof profile gmon.out > output

Entonces puede ver que el nombre del ejecutable y gmon.out se proporcionaron como argumentos para el comando gprof y la salida se redirigió a un archivo llamado «salida». Este archivo contiene todo el análisis estadístico del rendimiento del programa «perfil» en una forma legible por humanos.

El contenido del resultado se divide en tipos de información: perfil plano y gráfico de llamadas.

perfil plano

Aquí está el análisis estadístico en forma de perfil plano:

análisis estadístico gprof

Las estadísticas que se muestran arriba se conocen como perfil plano. Aquí está la explicación (tomada del archivo de salida) de lo que significa cada columna:

  • % tiempo – El porcentaje del tiempo de ejecución total del programa utilizado por esta función.
  • Segundos acumulados – Una suma acumulada del número de segundos representados por esta función y los enumerados anteriormente.
  • Segundos propios – El número de segundos representados por esta función únicamente. Este es el tipo principal de esta lista.
  • llamar – Cuántas veces se invocó esta función, si esta función está perfilada, de lo contrario, en blanco.
  • Automs/llamada – La cantidad promedio de milisegundos dedicados a esta función por llamada, si esta función está perfilada; de lo contrario, está vacía.
  • Total ms/llamada – La cantidad promedio de milisegundos empleados en esta función y su descendiente por llamada, si esta función está perfilada; de lo contrario, en blanco.
  • Nombre – Nombre de la función. Este es el tipo menor para esta lista. El índice muestra la ubicación de la función en la lista gprof. Si el índice está entre paréntesis, muestra dónde aparecería en la lista gprof si se imprimiera.

llamar al gráfico

Aquí está el análisis estadístico en forma de gráfico de llamadas:

gráfico de llamada de análisis estadístico gprof

Esta tabla describe el árbol de llamadas del programa y ha sido ordenada por el tiempo total empleado en cada función y sus hijos. Cada entrada en esta tabla consta de varias filas. La línea de números de índice en el margen izquierdo enumera la función actual. Las líneas de arriba listan las funciones que llamaron a esta función, y las líneas de abajo listan las funciones a las que llamó.

Aquí está la explicación (tomada del archivo de salida) de lo que significa cada columna:

  • Índice – Un número único asignado a cada elemento de la tabla. Los números de índice se ordenan numéricamente. El número de índice está impreso junto a cada nombre de función, lo que facilita buscar dónde se encuentra la función en la tabla.
  • % tiempo – Este es el porcentaje del tiempo «total» dedicado a esta función y sus hijos. Tenga en cuenta que debido a diferentes puntos de vista, características excluidas de las opciones, etc., estos números NO sumarán el 100 %.
  • Uno mismo – Esta es la cantidad total de tiempo dedicado a esta función. Para los padres de función, este es el período de tiempo que se propagó directamente desde la función a este padre. Mientras que, para funciones secundarias, esta es la cantidad de tiempo que se propagó directamente del elemento secundario a la función.
  • NIÑOS – Esta es la cantidad total de tiempo propagado a esta función por sus hijos. Para los padres de función, este es el período de tiempo que se propagó de los hijos de la función a este padre. Mientras que, para los hijos de función, esta es la cantidad de tiempo que se propagó desde los hijos del hijo a la función.
  • Llamó – Esta es la cantidad de veces que se llamó a la función. Si la función se llamó de forma recursiva, el número incluye solo llamadas no recursivas y va seguido de un «+» y el número de llamadas recursivas. Para padres de función, este es el número de veces que este padre llamó a la función `/’ el número total de veces que se llamó a la función. Las llamadas a funciones recursivas no se incluyen en el conteo después de ‘/’. Mientras que, para funciones secundarias, este es el número de veces que la función llamó a este elemento secundario ‘/’, el número total de veces que se llamó al elemento secundario. Las llamadas recursivas secundarias no se enumeran en el número después de ‘/’.
  • Nombre – El nombre de la función actual. El número de índice se imprime después. Si la función es miembro de un ciclo, el número de ciclo se imprime entre el nombre de la función y el número de índice. Para padres de función, este es el nombre del padre. El número de índice del padre se imprime después. Si el padre es miembro de un ciclo, el número de ciclo se imprime entre el nombre y el número de índice. Para los hijos de la función, este es el nombre del hijo. El número de índice del niño está impreso después. Si el niño es miembro de un ciclo, el número de ciclo se imprime entre el nombre y el número de índice.

Toda la explicación mencionada anteriormente también está presente en el archivo de salida generado por gprof. Lo he mencionado aquí para comodidad de los lectores.

Nota: Toda esta explicación se produce en el archivo de salida cada vez que se ejecuta gprof. Entonces, una vez que comprenda los detalles, puede usar la opción de línea de comando gprof -b. Para leer más opciones de línea de comando, lea página del manual de gprof.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba
Cerrar