Гид по технологиям

Профилирование производительности в Linux с помощью gprof

5 min read Производительность Обновлено 19 Nov 2025
gprof: профилирование в Linux
gprof: профилирование в Linux

Введение

Производительность — одна из ключевых проблем при разработке ПО. Профилирование помогает найти узкие места, мёртвый код и скрытые ошибки. В экосистеме GNU для этого существует утилита gprof, которая удобна для простого и быстрого получения данных о вызовах функций и времени их выполнения.

Важно: gprof работает на уровне функции (sampling + вызовы), поэтому он хорош для поиска «горячих» функций, но не всегда показывает проблемы на уровне системных вызовов или параллелизма.

Установка

В большинстве дистрибутивов gprof уже входит в пакет binutils. Если на вашей системе он отсутствует, установите пакет через менеджер пакетов.

Debian/Ubuntu:

sudo apt-get install binutils

RHEL/CentOS/Fedora:

sudo yum install binutils

После установки доступна команда gprof и генерация профайлинговых данных через компоновку с опцией -pg.

Требования и опции компилятора

Чтобы gprof собирал данные, исполняемый файл должен быть скомпилирован и слинкован с опцией -pg. Для gcc/clang это выглядит так:

gcc -Wall -pg test.c -o test

Если вы разделяете этапы компиляции и линковки, добавьте -pg и туда, и туда. Для аннотированных листингов добавьте также -g (символы отладки).

Кратко:

  • -pg — включить подсчёт профиля (обязательна при сборке и линковке)
  • -g — сохранить отладочные символы (нужно для аннотации исходников)

Пример программы

Ниже — минимальный рабочий пример на C, который можно использовать для демонстрации работы gprof.

#include 

void func2()
{
    volatile int count = 0;
    for (int i = 0; i < 1000000; ++i) {
        count += i % 3;
    }
}

void func1()
{
    for (int i = 0; i < 10; ++i) {
        func2();
    }
}

int main()
{
    func1();
    printf("Done\n");
    return 0;
}

Этот код вызывает func2 многократно, поэтому profiler покажет func2 как «горячую» функцию.

Компиляция, запуск и генерация отчёта

  1. Скомпилируйте с -pg:
gcc -Wall -pg test.c -o test
  1. Запустите программу как обычно:
./test
  1. После нормального завершения в текущей директории появится файл gmon.out. Он содержит сырые данные профилирования.

  2. Сгенерируйте человеко-читаемый отчёт:

gprof test gmon.out > prof_output.txt

Файл prof_output.txt будет содержать Flat profile и Call graph.

Important: gmon.out создаётся только при нормальном завершении процесса. Если программа завершилась через _exit() или была убита сигналом, файл может не появиться или быть неполным.

Разбор вывода gprof

Отчёт обычно разделён на две основные секции:

  • Flat profile — список функций, сколько времени было потрачено непосредственно в каждой функции, число вызовов и среднее время на вызов.
  • Call graph — дерево вызовов, показывающее, кто кого вызывает и как распределяется время между родителем и дочерними функциями.

Пример упрощённого фрагмента Flat profile:

Each sample counts as 0.01 seconds.
%   cumulative   self              self     total             name
time   seconds   seconds    calls  ms/call  ms/call
100.00   1.00    1.00          10    0.100    0.100   func2
0.00    1.00    0.00           1    0.000    0.000   func1

И пример упрощённого Call graph:

index %time    self  children    called     name
[1] 100.00    1.00   0.00        10/10     func2
[2]  0.00     0.00   1.00         1/1      func1

Поля объясняются в начале prof_output; при желании подробные пояснения можно отключить ключом -b (brief):

gprof -b test gmon.out > prof_output.txt

Полезные советы и ограничения

  • Файл gmon.out создаётся в текущей рабочей директории; убедитесь, что есть права на запись.
  • gprof использует семплирование времени и статический анализ вызовов, поэтому он может не точно отражать поведение многопоточных программ или коротких/быстрых функций.
  • Для детального анализа исполнения на уровне строк используйте опции -g при компиляции и ключ -A у gprof:
gcc -Wall -pg -g test.c -o test
gprof -A test gmon.out > annotated.txt
  • Для визуализации call graph используйте внешний инструмент gprof2dot, который преобразует вывод в граф (dot) и даст возможность строить PNG/SVG.

Альтернативные инструменты

Если gprof не даёт нужной информации, рассмотрите альтернативы:

  • perf (Linux perf) — низкоуровневое профилирование, хорош для системных вызовов и контекстов ядра.
  • Valgrind/Callgrind + KCacheGrind — детальное профилирование и визуализация на уровне вызовов и строк.
  • gperftools (Google Performance Tools) — встроенный CPU profiler с низкой нагрузкой.
  • eBPF-инструменты (bcc, bpftrace) — для профайлинга в продакшн без модификации бинарников.
  • py-spy / rbspy — для профайлинга интерпретируемых языков (Python/Ruby) без перезапуска.

Мини-методика профилирования (шаги)

  1. Изолируйте сценарий выполнения, который нужно профилировать (репрезентативный набор данных).
  2. Соберите бинарник с -pg (и -g при необходимости).
  3. Запустите программу до завершения, получите gmon.out.
  4. Сформируйте отчёт gprof и проанализируйте Flat profile и Call graph.
  5. При необходимости аннотируйте исходники (-A) и/или визуализируйте граф.
  6. Внесите изменения, повторите профилирование и сравните результаты.

Ролевые чек-листы

Для разработчика:

  • собрать с -pg и -g
  • прогнать репрезентативный сценарий
  • сохранить prof_output и gmon.out для сравнения

Для QA/инжера по производительности:

  • воспроизвести сценарий в контролируемой среде
  • проверить влияние оптимизаций и изменений архитектуры

Для релизного инженера/админа:

  • убедиться, что профилирование не включено в релизную сборку по умолчанию (избегать -pg в проде)
  • при необходимости собирать отдельные демо-артефакты для анализа

Критерии приёмки

  • Идентифицированы «горячие» функции, отвечающие за значительную часть времени выполнения.
  • Внесённая оптимизация уменьшила время выполнения на проверенном сценарии или снизила нагрузку CPU/памяти.
  • Результаты воспроизводимы и зафиксированы для регресс-тестов.

Глоссарий

  • gprof — GNU profiler, инструмент для профилирования приложений на уровне функций.
  • gmon.out — бинарный файл, создаваемый приложением при сборе профиля.
  • Flat profile — табличный отчёт, показывающий время, проведённое в каждой функции.
  • Call graph — граф вызовов функций с распределением времени между родителями и детьми.

Итог

gprof остаётся простым и удобным инструментом для быстрого получения представления о распределении времени между функциями в приложении. Для сложных сценариев и продакшн-анализа полезно комбинировать его с более современными инструментами (perf, eBPF, Valgrind). Всегда закрепляйте и документируйте профили перед изменениями, чтобы можно было объективно сравнить результаты.

Notes: если нужна инструкция по визуализации через gprof2dot или пример использования perf, я могу добавить шаги и примеры команд.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Шифрование USB‑накопителя с VeraCrypt
Безопасность

Шифрование USB‑накопителя с VeraCrypt

PowerShell: история команд — просмотр и сохранение
PowerShell

PowerShell: история команд — просмотр и сохранение

Nandroid — полная резервная копия Android
Android.

Nandroid — полная резервная копия Android

Ошибка 0x800f0806 в Windows 11 22H2
Windows 11

Ошибка 0x800f0806 в Windows 11 22H2

Извлечь ссылки с веб‑страницы PowerShell
Automation

Извлечь ссылки с веб‑страницы PowerShell

Подписи в Gmail для нескольких адресов
Email

Подписи в Gmail для нескольких адресов