Perfilado de código C++: encontramos cuellos de botella para principiantes

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿por qué es importante perfilar código C++?

\n

C++ es uno de los lenguajes de programación más rápidos, pero incluso en él se puede escribir código lento. A menudo, los desarrolladores pasan horas optimizando partes del programa que no lo necesitan, guiándose por la intuición. El perfilado es un enfoque científico para la optimización: se mide dónde el programa pasa más tiempo y se mejoran específicamente esas áreas.

\n

Para los programadores principiantes de C++, el perfilado puede parecer complejo, pero en realidad las herramientas básicas se aprenden en una tarde. En este artículo, analizaremos tres herramientas populares: gprof, perf y Valgrind, y aprenderemos a interpretar sus resultados.

\n\n

¿Qué es el perfilado y qué métodos existen?

\n

El perfilado es la recopilación de datos sobre el funcionamiento de un programa durante su ejecución. Existen dos enfoques principales:

\n
    \n
  • Perfilado por instrumentación — se añaden "sondas" especiales al código del programa (por ejemplo, gprof). Desventaja: ralentiza la ejecución del programa.
  • \n
  • Perfilado por muestreo — a intervalos regulares "observa" el programa y registra qué función se está ejecutando en ese momento (por ejemplo, perf). Casi no ralentiza el programa.
  • \n
\n

También existen herramientas para buscar fugas de memoria (Valgrind) y analizar la caché. Para empezar, es suficiente dominar gprof y perf.

\n\n

Herramienta 1: gprof — el clásico del perfilado

\n

gprof es un perfilador integrado para GCC. Funciona en dos etapas: recopilación de datos y su análisis.

\n

Cómo usar gprof

\n

Primero, compile el programa con la bandera -pg:

\n
g++ -pg -o my_program my_program.cpp
\n

Ejecute el programa:

\n
./my_program
\n

Después de la ejecución, aparecerá el archivo gmon.out. Ahora ejecute gprof:

\n
gprof my_program gmon.out > report.txt
\n

Abra report.txt y observe la tabla:

\n
Flat profile:\nEach sample counts as 0.01 seconds.\n  %   cumulative   self              self     total\n time   seconds   seconds    calls  ms/call  ms/call  name\n 60.00      0.06     0.06    10000     0.01     0.01  slow_function\n 30.00      0.09     0.03     5000     0.01     0.02  medium_function\n 10.00      0.10     0.01        1    10.00    10.00  main
\n

En la columna % time se muestra el porcentaje de tiempo que ocupó la función. En nuestro ejemplo, slow_function es el principal candidato para la optimización.

\n

Consejo: Para programas pequeños, gprof es excelente. Para proyectos grandes, puede dar datos inexactos debido a las optimizaciones del compilador.

\n\n

Herramienta 2: perf — potente muestreador para Linux

\n

perf es un perfilador integrado en el núcleo de Linux. Funciona mediante el método de muestreo y casi no ralentiza el programa. Es ideal para sistemas en producción.

\n

Uso básico de perf

\n

Compile el programa con símbolos de depuración (bandera -g):

\n
g++ -g -o my_program my_program.cpp
\n

Inicie el perfilado:

\n
perf record ./my_program
\n

Después de que el programa termine, vea el informe:

\n
perf report
\n

Verá una interfaz interactiva. Al hacer clic en una función, puede ver qué líneas de código se ejecutaron con más frecuencia. Ejemplo de salida:

\n
Samples: 1K of event 'cycles'\nEvent count (approx.): 250000000\nOverhead  Command      Shared Object     Symbol\n  45.32%  my_program   my_program        [.] slow_function\n  30.15%  my_program   my_program        [.] medium_function\n  12.50%  my_program   libc-2.31.so      [.] malloc\n   8.03%  my_program   my_program        [.] main
\n

Importante: perf requiere permisos de root para recopilar datos del núcleo

Blogs

Book Recommendations