Perfilamento de código C++: encontrando gargalos para iniciantes

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que é importante perfilar código C++?

\n

C++ é uma das linguagens de programação mais rápidas, mas mesmo nela é possível escrever código lento. Frequentemente, desenvolvedores gastam horas otimizando partes erradas do programa, guiados pela intuição. O perfilamento é uma abordagem científica para a otimização: você mede onde o programa gasta mais tempo e melhora esses pontos de forma direcionada.

\n

Para programadores C++ iniciantes, o perfilamento pode parecer complexo, mas na verdade as ferramentas básicas são aprendidas em uma noite. Neste artigo, vamos explorar três ferramentas populares: gprof, perf e Valgrind, e aprender a interpretar seus resultados.

\n\n

O que é perfilamento e quais são os métodos existentes?

\n

Perfilamento é a coleta de dados sobre o funcionamento de um programa durante sua execução. Existem duas abordagens principais:

\n
    \n
  • Perfilamento por instrumentação — "sondas" especiais são adicionadas ao código do programa (ex.: gprof). Desvantagem: diminui a velocidade de execução do programa.
  • \n
  • Perfilamento por amostragem — em intervalos regulares, "observa" o programa e registra qual função está sendo executada no momento (ex.: perf). Quase não diminui a velocidade do programa.
  • \n
\n

Existem também ferramentas para encontrar vazamentos de memória (Valgrind) e análise de cache. Para começar, é suficiente dominar gprof e perf.

\n\n

Ferramenta 1: gprof — o clássico do perfilamento

\n

gprof é um profiler integrado ao GCC. Ele funciona em duas etapas: coleta de dados e análise.

\n

Como usar o gprof

\n

Primeiro, compile o programa com a flag -pg:

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

Execute o programa:

\n
./my_program
\n

Após a execução, o arquivo gmon.out será gerado. Agora execute o gprof:

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

Abra o report.txt e observe a tabela:

\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

Na coluna % time é mostrada a porcentagem de tempo que a função consumiu. No nosso exemplo, slow_function é a principal candidata para otimização.

\n

Dica: Para programas pequenos, o gprof é excelente. Para projetos grandes, ele pode fornecer dados imprecisos devido às otimizações do compilador.

\n\n

Ferramenta 2: perf — um poderoso amostrador para Linux

\n

perf é um profiler integrado ao kernel Linux. Ele funciona por amostragem e quase não diminui a velocidade do programa. É ideal para sistemas em produção.

\n

Uso básico do perf

\n

Compile o programa com símbolos de depuração (flag -g):

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

Inicie o perfilamento:

\n
perf record ./my_program
\n

Após a conclusão do programa, visualize o relatório:

\n
perf report
\n

Você verá uma interface interativa. Ao clicar em uma função, é possível ver quais linhas de código foram executadas com mais frequência. Exemplo de saída:

\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: O perf requer privilégios de root para coletar dados do kernel

Blogs

Book Recommendations