Skip to content

barsgroup/mono-ssp

Repository files navigation

Mono Stack Sampling Profiler

Эта утилита предназначена для статистического (сэмплирующего) профилирования приложений, работающих под Mono в Linux-x86_64.

Особенность этого способа профилирования заключается в том, что в результате получается диаграмма распределения полного времени ("wall time") на выполнение отдельных методов. В полное время входит on-CPU-время (т.е., время на непосредственное выполнение кода), так и off-CPU-время (время, потраченное на ожидание ввода-вывода или на синхронизацию).

Как использовать

Требования к профилируемому процессу

Предварительно следует установить пакеты с отладочной информацией для используемых библиотек. В частости, под CentOS/Fedora следует установить пакет mono-core-debuginfo.

Следует отдельно запустить профилируемый процесс. Очень важно, чтобы при запуске процесса были учтены:

  • должна быть указана переменная окружения MONO_DEBUG=disable_omit_fp
  • к команде запуска mono должен быть добавлен аргумент --jitmap.

Пример запуска ASP.NET-приложения из командной строки для профилирования:

$ cd /path/to/web-app
$ MONO_DEBUG=disable_omit_fp /usr/bin/mono --jitmap /usr/lib/mono/4.5/xsp4.exe --nonstop --port=5000

Запуск профилирования

Профилировщик можно запускать из командной строки:

$ ./mono_ssp --pid "$(pgrep -f 'mono.*xsp4.exe')" --perf_script --duration_sec 120 --interval_ms 1 > prof.txt

Следует указать следующие параметры запуска:

  • --pid PID. Идентификатор профилируемого процесса
  • --perf_script и > prof.txt. Опция --perf_script означает, что на стандартный вывод будут выводиться сэмплы в формате, совпадающем с форматом вывода утилиты perf script. > prof.txt - это перенеправление стандартного вывода в файл.
  • --duration_sec SECONDS. Указывается длительность профилирования в секундах (можно указывать только целое количество секунд)
  • --interval_ms MILLISECONDS. Периодичность снятия сэмплов (в миллисекундах). (Замечание: т.к. сейчас скорость снятия сэмплов маленькая, то указанная периодичность не гарантируется).

При успешном выполнении будет выведено сообщение:

Profile completed. Took 133 process samples in 120.227 seconds

и сформирован файл prof.txt (файл содержит сырые (необработанные) результаты профилирования).

Использование результатов профилирования

Для анализа результатов профилирования рекомендуется использовать один из 2 инструментов - FlameGraph и speedscope.

FlameGraph

FlameGraph - это обзорная визуализация распределения времени по стэктрейсам. см. http://www.brendangregg.com/flamegraphs.html для более подробного описания.

Для построения flamegraph'а следует:

  • Склонировать репозиторий https://github.com/brendangregg/FlameGraph

  • Запустить утилиту flamegraph:

    $ /path/to/FlameGraph/stackcollapse-perf.pl < prof.txt | /path/to/FlameGraph/flamegraph.pl > prof.flamegraph.svg
    

    (где prof.txt - это файл с сырыми результатами профилирования)

speedscope

speedscope - это инструмент для интерактивного анализа результатов трассировки и профилирования.

Его можно открывать в браузере по адресу https://www.speedscope.app/ (файлы с результатами профилирования не передаются в интернет и полностью анализируются в браузере) или установить локально через NPM.

Описание вариантов запуска и установки: https://github.com/jlfwong/speedscope#usage

Так как speedscope умеет открыть файлы в формате perf script, то достаточно открыть speedscope и импортировать файл с результатами профилирования (prof.txt).

Как интерпретировать результаты

Утилита mono-ssp основана на периодическом сборе (сэмплировании) стэков вызовов всех нитей (потоков) процесса. В отличие от CPU-профилировщиков (например, perf record (кроме отдельных специфических режимов)), в этом результате учитывается время ожидания (ожидания ответа от БД, ожидание чтения данных с диска или по сети) и синхронизации (блокировки, ожидание окончания сборки мусора, бесконечное ожидание, ожидание задач из очереди задач). Для того, чтобы точнее сказать, в чем причина долгой операции (большое потребление CPU или большое ожидание) - следует произвести также CPU-профилирование и сравнить их результаты.

В результате профилирования будет много стэктрейсов, оканчивающихся на pthread_cond_timedwait, nanosleep и т.п. Их обычно можно игнорировать.

FlameGraph схлопывает стэки всех нитей (потоков), поэтому в нем большие одинаковые участки графика можно игнорировать - они соответствуют нитям, которые ожидают работы и не потребляют ресурсов.

Если цепочка вызовов в стэктрейсе оканчивается на sigsuspend - то это, вероятно, ожидание завершения сборки мусора в Mono.

Сборка кода

Для сборки необходимо наличие:

  • g++
  • meson
  • ninja
  • libunwind и libunwind-dev

Шаги сборки:

  • Скачать исходники mono-ssp

  • Создать где-нибудь временный каталог и перейти в этот каталог

  • В созданном каталоге выполнить команды:

    $ meson /path/to/mono-ssp --buildtype release
    $ ninja
    
  • В результате получится исполняемый файл meson_ssp (и набор промежуточных файлов).