Tarantool CE/EE Documentation portal logo
Помощь
Обновлена 15 сентября 2026 г. в 08:55

Профилировщик платформы LuaJIT

Стандартные параметры профилирования LuaJIT недостаточно детальны для полного анализа производительности. Например, perf отображает только стек хоста, поэтому все вызовы Lua показываются как единый pcall(). Наоборот, модуль jit.p, поставляемый с LuaJIT, не дает информации о стеке хоста.

Начиная с версии 2.10.0, в Tarantool встроен модуль misc.sysprof, реализующий сэмплинг-профилировщик платформы LuaJIT (далее в этом разделе – профилировщик платформы). Профилировщик платформы может одновременно фиксировать стеки гостя и хоста, а также состояния виртуальной машины, показывая полную картину происходящего.

Доступны три режима профилирования:

  • Default: показывает только счетчики состояний виртуальной машины.
  • Leaf: показывает последний кадр в стеке.
  • Callchain: выполняет полный дамп стека.

Вместе с профилировщиком платформы поставляется парсер по умолчанию, формирующий вывод в формате, подходящем для flamegraph.pl.

Работа с профилировщиком платформы

Использование профилировщика платформы включает два шага:

  1. Сбор данных и формирование бинарного профиля стеков (далее – сэмплинг-профиль).
  2. Разбор собранного сэмплинг-профиля для получения человекочитаемого отчета профилирования.

Сбор данных и формирование сэмплинг-профиля

Чтобы собрать сэмплинг-профиль для определенного участка кода на Lua и C, этот участок нужно поместить между двумя функциями модуля misc.sysprof, а именно - misc.sysprof.start() и misc.sysprof.stop() – а затем выполнить код в Tarantool.

Ниже приведен фрагмент Lua-кода с именем test.lua иллюстрирующий это.

local function payload()  local function fib(n)    if n <= 1 then      return n    end    return fib(n - 1) + fib(n - 2)  end  return fib(32)endpayload()local res, err = misc.sysprof.start({mode = 'C', interval = 1, path = 'sysprof.bin'})assert(res, err)payload()res, err = misc.sysprof.stop()assert(res, err)
Пример кода test.lua

Lua-код для запуска профилировщика платформы – как в строке 13 в приведенном выше примере test.lua – выглядит так:

local str, err = misc.sysprof.start({mode = 'C', interval = 1, path = 'sysprof.bin'})

где:

  • mode – режим профилирования;
  • interval – интервал сэмплирования;
  • sysprof.bin – имя бинарного файла, в который записываются события профилирования.

Если операция завершается неудачей – например, не удается открыть файл для записи или профилировщик платформы уже запущен – misc.sysprof.start() возвращает nil в качестве первого результата, строку с сообщением об ошибке в качестве второго результата и зависящий от системы код ошибки в качестве третьего результата.

При успешном выполнении misc.sysprof.start() возвращает true.

Lua-код для остановки профилировщика платформы – как в строке 18 в приведенном выше примере test.lua – выглядит так:

local res, err = misc.sysprof.stop()

Если операция завершается неудачей – например, при ошибке закрытия файлового дескриптора или при сбое во время формирования отчета – misc.sysprof.stop() возвращает nil в качестве первого результата, строку с сообщением об ошибке в качестве второго результата и зависящий от системы код ошибки в качестве третьего результата.

При успешном выполнении misc.sysprof.stop() возвращает true.

Чтобы сгенерировать файл с профилем в бинарном формате (в примере кода test.lua выше имя такого файла – sysprof.bin), выполните код в Tarantool:

$ tarantool test.lua
Запуск кода в Tarantool

Tarantool собирает события профилирования в sysprof.bin, помещает файл в рабочий каталог и закрывает сессию.

Разбор сэмплинг-профиля и формирование отчета профилирования

После получения профиля платформы в бинарном формате следующим шагом является его разбор для получения человекочитаемого отчета профилирования. Это можно сделать с помощью Tarantool посредством следующей команды (обратите внимание на дефис - перед именем файла):

$ tarantool -e 'require("sysprof")(arg)' - sysprof.bin > tmp$ curl -O https://raw.githubusercontent.com/brendangregg/FlameGraph/refs/heads/master/flamegraph.pl$ perl flamegraph.pl tmp > sysprof.svg
Разбор сэмплинг-профиля

где sysprof.bin – сэмплинг-профиль, сгенерированный ранее командой tarantool test.lua.

Что касается исследования Lua-кода с помощью отчетов профилирования, то здесь все зависит от конкретного кода, и точных рекомендаций на этот счет быть не может. Тем не менее, некоторые моменты рассмотрены далее в примере анализа отчета профилирования ниже.

Lua API профилировщика платформы

Профилировщик платформы предоставляет Lua-интерфейс:

  • misc.sysprof.start(opts);
  • misc.sysprof.stop();
  • misc.sysprof.report().

Первые две функции возвращают булевы значения res и err, где err равен nil при успешном выполнении и содержит сообщение об ошибке при неудаче.

misc.sysprof.report возвращает Lua-таблицу, содержащую следующие счетчики:

{  "samples" = int,  "INTERP" = int,  "LFUNC" = int,  "FFUNC" = int,  "CFUNC" = int,  "GC" = int,  "EXIT" = int,  "RECORD" = int,  "OPT" = int,  "ASM" = int,  "TRACE" = int}

Аргумент opts функции misc.sysprof.start может содержать следующие параметры:

  • mode (обязательный) – один из поддерживаемых режимов профилирования:

    • 'D' = DEFAULT;
    • 'L' = LEAF;
    • 'C' = CALLGRAPH.
  • interval (необязательный) – интервал сэмплирования в миллисекундах (по умолчанию 10 мс).

  • path (необязательный) – путь к файлу для хранения данных профиля (по умолчанию sysprof.bin).

C API профилировщика платформы

Профилировщик платформы предоставляет низкоуровневый C-интерфейс:

  • int luaM_sysprof_set_writer(sp_writer writer) – устанавливает функцию записи для sysprof.
  • int luaM_sysprof_set_on_stop(sp_on_stop on_stop) – устанавливает функцию обратного вызова при остановке для sysprof (для очистки ресурсов).
  • int luaM_sysprof_set_backtracer(sp_backtracer backtracer) – устанавливает функцию обратной трассировки. Если аргумент backtracer равен NULL, устанавливается функция обратной трассировки по умолчанию.

Все функции возвращают 0 при успешном выполнении и код ошибки при неудаче.

Конфигурационные C-типы

Параметры конфигурации профилировщика платформы включают:

  • typedef size_t (*sp_writer)(const void **data, size_t len, void *ctx) – функция записи для событий профиля.

    Должна быть async-safe, см. также man 7 signal-safety.

    Должна возвращать количество записанных байт при успешном выполнении или ноль в случае ошибки.

    Установка *data в NULL означает конец профилирования. Подробности см. в lj_wbuf.h.

  • typedef int (*sp_on_stop)(void *ctx, uint8_t *buf) – функция обратного вызова при остановке профилировщика платформы.

    Требуется для корректной очистки при финализации VM, если профилировщик платформы все еще работает.

    Возвращает ноль при успешном выполнении.

  • typedef void (*sp_backtracer)(void *(*frame_writer)(int frame_no, void *addr)) – функция обратной трассировки для стека хоста.

    Должна вызывать frame_writer для каждого кадра в стеке в порядке от вершины стека к его основанию.

    Функция frame_writer реализована внутри sysprof и передается в функцию backtracer.

    Если frame_writer возвращает NULL, обратная трассировка должна быть остановлена. Если frame_writer возвращает не NULL, обратная трассировка должна быть продолжена, если остались кадры.

Параметры профилировщика платформы

Структура параметров для luaM_sysprof_start выглядит следующим образом:

struct luam_Sysprof_Options {  /* Режим профилирования. */  uint8_t mode;  /* Интервал сэмплирования в мс. */  uint64_t interval;  /* Пользовательский буфер для записи данных. */  uint8_t *buf;  /* Размер буфера. */  size_t len;  /* Контекст для функции записи профиля и финального обратного вызова. */  void *ctx;};

Режимы профилирования

Профилировщик платформы поддерживает три режима профилирования:

  • Режим DEFAULT собирает только данные для luam_sysprof_counters, которые хранятся в памяти и могут быть получены с помощью luaM_sysprof_report после остановки профилировщика платформы.
  • Режим LEAF = DEFAULT + потоковая передача сэмплов, содержащих только верхние кадры стеков хоста и гостя в формате, описанном в lj_sysprof.h.
  • Режим CALLGRAPH = DEFAULT + потоковая передача сэмплов с полными цепочками вызовов стеков хоста и гостя в формате, описанном в lj_sysprof.h.
#define LUAM_SYSPROF_DEFAULT 0#define LUAM_SYSPROF_LEAF 1#define LUAM_SYSPROF_CALLGRAPH 2

Счетчики профилирования

Структура счетчиков для luaM_sysprof_report выглядит следующим образом:

struct luam_Sysprof_Counters {  uint64_t vmst_interp;  uint64_t vmst_lfunc;  uint64_t vmst_ffunc;  uint64_t vmst_cfunc;  uint64_t vmst_gc;  uint64_t vmst_exit;  uint64_t vmst_record;  uint64_t vmst_opt;  uint64_t vmst_asm;  uint64_t vmst_trace;  uint64_t samples;};

Предостережения

  • Задание функций записи, обратной трассировки и других параметров в режиме Default не имеет смысла, поскольку в этом режиме собираются только счетчики.
  • Для sysprof НЕТ конфигурации по умолчанию, поэтому luaM_Sysprof_Configure должен быть вызван перед первым запуском sysprof. Учитывайте требования async safety.