В этой задаче вам дан набор бенчмарков. В каждом бенчмарке есть performance bug. Вы должны найти этот баг, используя профилировщик, и исправить его.
Важно: В описании PR оставьте максимально подробный отчёт о том, как именно искали и нашли проблему в каждом случае, и как пришли к методу её исправления. Приложите скриншоты релевантных результатов профилировщика.
Менять суть алгоритмов запрещается, только их реализацию.
Также нельзя менять функции, отвечающие за сами бенчмарки (начинаются с bm_
).
Задания:
jpeg
- найти bottleneck и ускорить бенчмарк в 6 раз.pi
- найти bottleneck и ускорить бенчмарк в 50 раз.radix_sort
- найти bottleneck и ускорить бенчмарк на 30%.json
- понять, что тормозит, и ускорить бенчмарк в 2 раза, не меняя сами структуры.logger
- найти bottleneck и ускорить бенчмарк в 40 раз. Смысл классаLogger
должен остаться прежним. Содержимое лога должно остаться таким же, как и до ваших изменений.
Профилировать нужно с пресетом RelWithDebInfo
.
Не забудьте выбрать его, если используете CLion.
Руками его можно выставить, передав в CMake аргумент --preset RelWithDebInfo
.
Также результат может существенно отличаться на разных компиляторах, в CI используется GCC-14.
Если вы используете perf
, возможно, вам помогут команды perf record
и perf report
, а также флаги -g
и --call-graph dwarf
.
Ещё полезное про perf
: https://www.brendangregg.com/perf.html.
Можно использовать и другие профилировщики, однако далее будет рассмотрен лишь сценарий использования perf
.
Для анализа результатов perf
можно пользоваться как обычным консольным perf report
, так и более удобным FlameGraph.
Чтобы нарисовать флейм-граф, нужно:
- Склонить его куда-нибудь (
git clone https://github.com/brendangregg/FlameGraph.git
) - В директории с собранным
perf.data
прогнать командуperf script > out.perf
(важно, чтобы профиль был собран с флагом-g
) - Находясь в директории, куда склонили FlameGraph, запустить команду
FlameGraph/stackcollapse-perf.pl <path to out.perf> > out.folded && FlameGraph/flamegraph.pl out.folded > fgraph.svg
Ещё один способ визуализации — gprof2dot, превращающий профиль в dot-граф.
Запускает командой по типу gprof2dot -f perf -o out.dot out.perf
, где out.perf
— результат запуска perf script
(см. выше часть про FlameGraph).
Warning
Работоспособность гарантируется только на Linux. На системах, отличных от Linux, рекомендуется использовать либо виртуалку (например, WSL), либо Docker.
По умолчанию в вашей системе могут быть установлены опции ядра, ограничивающие работу perf
, в частности perf_event_paranoid
и kptr_restrict
.
Их можно изменить до следующего перезапуска системы:
sudo sysctl kernel.perf_event_paranoid=1
sudo sysctl kernel.kptr_restrict=0
Более подробную информацию о них можно найти здесь.
В наших контейнерах не установлен perf
, поскольку ему важна версия ядра Linux на вашем хосте. Вы можете доустановить его самостоятельно или замаунтить бинарь с хоста.
Чтобы perf
работал внутри докера, нужно добавить опцию --privileged
к docker run
.
Если вы пользуетесь Windows, то, чтобы заработал perf
в докер-контейнере, нужно сделать следующие шаги:
- Убедиться, что в Docker Desktop установлен WSL2 как бекенд https://docs.docker.com/desktop/windows/wsl/
- Cделать
wsl -l -v
, увидеть там работающий инстанс docker-desktop - Cделать
wsl -d docker-desktop
- Вы попадёте внутрь шелла WSL, там нужно выполнить
sysctl kernel.perf_event_paranoid=-1
- perf внутри докер-контейнера должен заработать.
Если вы пользуетесь MacOS, то возможно единственный путь это запускать докер-контейнер без указания user'а (то есть под рутом).
В этой задаче, как обычно, работает сборка и запуск через CLion, но возможностей встроенного в CLion профайлера вам может не хватить. Более того, мы настоятельно рекомендуем воспользоваться более низкоуровневыми тулами, так вы получите максимальную пользу от выполнения задания.
Чтобы собрать руками, можно выполнить следующие команды (при условии, что у вас уже настроено окружение аналогичное тому, что используется для запуска через CLion, то есть установлен vcpkg).
mkdir -p cmake-build-RelWithDebInfo
rm -rf cmake-build-RelWithDebInfo/*
cmake "-DCMAKE_TOOLCHAIN_FILE=<path-to-vcpkg>/vcpkg/scripts/buildsystems/vcpkg.cmake" -GNinja --preset RelWithDebInfo -S .
cmake --build cmake-build-RelWithDebInfo
Бинари для каждой из подзадач будут лежать в cmake-build-RelWithDebInfo/perf
, дальше их можно использовать для запуска под perf
.