perf, VTune и flame graphs: профилирование
Тема дорожной карты · Modern C++ Developer
Профилирование отвечает на единственный вопрос, который имеет значение при оптимизации: где именно программа тратит время. Интуиция здесь подводит даже опытных разработчиков, поэтому в C++-проектах измеряют, а не угадывают. Три инструмента закрывают почти все сценарии: perf из состава ядра Linux собирает сэмплы с минимальными накладными расходами, Intel VTune даёт микроархитектурный разбор (промахи кэша, неверные предсказания ветвлений, задержки конвейера), а flame graphs превращают тысячи стеков в одну картинку, по которой горячие пути видны за секунды.
Как это работает
perf использует аппаратные счётчики производительности (PMU) и механизм сэмплирования: несколько тысяч раз в секунду процессор прерывается, и ядро записывает текущий стек вызовов. Команда perf record -g ./app собирает такие сэмплы в файл, а perf report агрегирует их по функциям. Чем чаще функция попадает в сэмплы, тем больше времени она занимает. Для корректных стеков в релизной сборке нужны либо frame pointers (-fno-omit-frame-pointer), либо режим --call-graph dwarf, который разворачивает стек по отладочной информации.
VTune работает похожим образом, но добавляет анализ на уровне микроархитектуры. Режим Hotspots показывает горячие функции, а Microarchitecture Exploration раскладывает время по методологии Top-Down: сколько тактов ушло на фронтенд (декодирование инструкций), на бэкенд (ожидание памяти и исполнительных блоков), на неверные предсказания и на полезную работу. Именно этот разрез объясняет, почему функция медленная, а не только где она медленная.
Flame graph, придуманный Бренданом Греггом, строится из тех же стеков: скрипты stackcollapse-perf.pl и flamegraph.pl схлопывают одинаковые стеки и рисуют SVG, где ширина прямоугольника пропорциональна доле времени, а вертикаль соответствует глубине вызовов. Широкие плато наверху графика и есть кандидаты на оптимизацию.
Когда применять
Начинайте с perf, когда нужен быстрый ответ на production-подобной машине: инструмент есть в любом дистрибутиве, не требует перекомпиляции и вносит накладные расходы около одного процента. Flame graph подключайте сразу после сбора данных, если стек глубокий и текстовый отчёт perf report не читается. VTune уместен на втором шаге, когда горячая функция уже найдена, а причина неочевидна: например, цикл выглядит простым, но Top-Down показывает, что 70% тактов конвейер ждёт данные из памяти. Для HFT-систем, обработки видео и вычислительных ядер такой анализ обязателен, потому что там разница между версиями измеряется промахами кэша, а не строками кода.
Типичные ошибки
Самая частая ошибка — профилировать debug-сборку. Без оптимизаций горячими становятся инлайнящиеся в релизе геттеры и проверки итераторов, и результат ничего не говорит о реальном коде. Собирайте с -O2 -g. Вторая ошибка — оптимизировать функцию с 3% времени, потому что она «выглядит плохо», игнорируя плато в 40%. Третья — измерять на ноутбуке с динамической частотой и не фиксировать governor, из-за чего прогоны отличаются на десятки процентов. Наконец, обрезанные стеки в flame graph («[unknown]») почти всегда означают отсутствие frame pointers в какой-то библиотеке; пересоберите зависимости или переключитесь на DWARF-развёртку.
Связанные понятия
Полезные ресурсы
🔤 Английские термины в этой теме
Слова из этой темы, которые русскоязычные часто произносят неверно. Кнопка 🔊 произносит голосом браузера.
- percent /pərˈsɛnt/ ударение на второй слог разбор: Версии и числа: two point oh, semver
- thousand /ˈθaʊzənd/ с «θ», не «таузенд» разбор: Версии и числа: two point oh, semver
- scenario /sɪˈnɑːrioʊ/ «синАриоу» разбор: Тестирование: flaky, coverage, mock, fixture, regression
- mandatory /ˈmændətəri/ обязательный разбор: Читаем man pages: SYNOPSIS, OPTIONS, скобки
- kernel /ˈkɜːrnəl/ «кёрнел», не «кернел» разбор: Английский Linux и терминала
- release /rɪˈliːs/ ударение на второй слог, «релис», а не «релиз» с русским «з» разбор: Версии и числа: two point oh, semver
- result /rɪˈzʌlt/ ударение на второй слог разбор: Behavioral questions и метод STAR