Ответ 1
Update
Майк недавно создал и выпустил замечательный легкий профайлер для LuaJIT, вы можете найти его здесь.
Update
В этой области wiki получил еще несколько страниц, особенно этот, в котором подробно описаны некоторые дополнительные материалы, не упомянутые в исходном ответе, и основан на сообщении почтового рассылки от Майка.
Недавно LuaJIT запустил собственный wiki и рассылка список, и с такими вещами приходит много, еще много камней об ускорении кода для LuaJIT.
Сейчас вики довольно тонкие (но всегда ищут людей, чтобы добавить к ней), однако одна замечательная страница, которая была добавлена недавно, - a список функций NYI. Функции NYI заставляют JIT выходить из строя и возвращаться к интерпретатору, поэтому вполне очевидно, что следует избегать функций NYI как можно больше на горячем пути, особенно в циклах.
Некоторые интересующие темы из списка рассылки:
И просто повторить сказанное ниже (потому что это просто полезно), -jv
- лучший инструмент для настройки производительности, он также должен стать вашей первой остановкой при устранении неполадок.
Оригинальный ответ
Я сомневаюсь, что вы найдете много на этом самом деле, главным образом, причина LJ2 все еще находится в стадии бета-тестирования, и поэтому большинство профилей выполняются наивно, поскольку нет никаких отладочных крюков для конкретных объектов LJ2, таких как рекордер.
С другой стороны, новый модуль FFI позволяет прямое обращение к таймерам с высоким разрешением (или профилирующим API, таким как VTune/CodeAnalyst), вы можете профилировать этот путь, но что-то еще требует расширений ядра LJ2 JIT, что не должно быть слишком жестким, так как код ясен и прокомментирован.
Один параметр командной строки рекордера (взятый из здесь):
Команды -jv и -jdump являются модулями расширения, написанными в Lua. Oни в основном используются для отладки самого компилятора JIT. Для описание их вариантов и формата вывода, пожалуйста, прочитайте блок комментариев в начале их источника. Их можно найти в lib каталога исходного дистрибутива или установленного под jit каталог. По умолчанию это /usr/local/share/luajit -2.0.0-beta8/jit на системах POSIX.
что означает, что вы можете использовать код модуля из команд для формирования на основе профилирующего модуля для LuaJIT 2.
Обновление
С обновлением вопроса, это становится немного легче ответить. Поэтому давайте начнем с источника, LuaJIT.org:
до ручного оптимизации кода, всегда полезно проверить настройки оптимизации оптимизации JIT:
Компиляция
На странице Running мы можем увидеть все параметры настройки параметров JIT, для оптимизации мы сосредоточимся на -O
. Сразу же Майк говорит нам, что включение всех оптимизаций имеет минимальное влияние на производительность, поэтому убедитесь, что вы работаете в -O3
(теперь это значение по умолчанию), поэтому единственными возможными здесь для нас реальными значениями являются пороги JIT и Trace.
Эти параметры очень специфичны для кода, который вы пишете, поэтому нет общих "оптимальных настроек", кроме стандартных значений, но, разумеется, если ваш код имеет много циклов, поэкспериментируйте с разворачиванием цикла и временем (но очистите кеш между каждым прогоном, если вы ищете производительность холодного запуска).
-jv
также полезен, чтобы помочь избежать проблем/ "резервных копий" , что приведет к спасению JIT.
Сам сайт не предлагает многое о том, как писать лучший или более оптимизированный код, за исключением некоторых небольших лакомых кусочков в учебное пособие FFI
Кэширование функций
Кэширование функций - хороший ускоритель производительности в Lua, но менее важно сосредоточиться на LuaJIT, поскольку JIT выполняет большинство этих оптимизаций, важно отметить, что кеширование функций FFI C плохое, желательно кэшировать пространство имен, в котором они находятся.
Пример со страницы:
плохо:
local funca, funcb = ffi.C.funcb, ffi.C.funcb -- Not helpful!
local function foo(x, n)
for i=1,n do funcb(funca(x, i), 1) end
end
хорошо:
local C = ffi.C -- Instead use this!
local function foo(x, n)
for i=1,n do C.funcb(C.funca(x, i), 1) end
end
Проблемы с производительностью FFI
раздел Status описывает различные конструкции и операции, которые ухудшают производительность кода (главным образом потому, что они не скомпилированы, но используют вместо этого резерв VM).
Теперь мы перейдем на источник для всех драгоценностей LuaJIT, список рассылки Lua:
-
Избегайте вызовов C и NYI Lua в циклах: если вы хотите, чтобы LJ2-трассировщик ударил и дал полезную обратную связь, вам необходимо избегать функций NYI (еще не реализовано) или вызовов C, в которых компилятор трассировки не может идти. Поэтому, если у вас есть небольшие вызовы C, которые можно импортировать в lua и использовать в цикле, импортируйте их, в худшем случае они могут быть на 6% медленнее, чем реализация компилятора C, в лучшем случае быстрее.
-
Используйте линейные массивы по ipairs: согласно Майку, пары /next будут всегда медленнее по сравнению с другими методами (есть также малый лакомый кусочек там о кэшировании символов для трассировщика).
-
Избегайте вложенных циклов: каждый уровень вложенности принимает дополнительный проход к трассировке и будет немного менее оптимизирован, особенно избегать внутренних петли с более низкими итерациями.
-
Вы можете использовать 0-базовые массивы: Майк говорит здесь, что LuaJIT не имеет штрафа за производительность для массивов на основе 0, в отличие от стандартных Lua.
-
Объявить локальных жителей в максимально возможной внутренней области: нет никаких реальных объяснений, почему, но IIRC это связано с Анализ жизнеспособности SSA. также содержит некоторую интересную информацию о том, как избежать слишком большого количества локальных жителей (которые нарушают анализ живости).
-
Избегайте множества крошечных циклов: это испортит эвристику разворачивания и замедлит код.
Меньшие лакомые кусочки:
- Рекомендации FFI
- по состоянию на бета8 мы имеем байт-код, который можно использовать для улучшения производительности холодного запуска, удалив шаг синтаксического анализа.
- Некоторые общие рекомендации по типам FFI от Mike
- Использовать метаданные как можно больше
- Ускорение Lua → C → Lua looping
- LJ2 не имеет Lua метатетируемые ошибки и избегает прокси-таблиц, чтобы он правильно кэшировал.
- обновить до Git HEAD, когда это возможно, оно всегда содержит исправления и ускорения.
Инструменты для профилирования доступны для обычного Lua, однако есть еще один новый проект, который официально совместим с LuaJIT (я сомневаюсь, что он будет использовать любую из функций LuaJIT в учетной записи), luatrace. В Liki wiki также есть страница советы по оптимизации для нормального Lua, они должны быть проверены на их эффективность в LuaJIT (большинство из этих оптимизаций вероятно, уже выполняются внутри), однако LuaJIT по-прежнему использует GC по умолчанию, это оставляет его в качестве одной из областей, где доходы от ручной оптимизации все еще могут быть большими (пока Майк не добавит пользовательский GC, о котором он говорил здесь и там).
Источник LuaJIT содержит несколько настроек для работы с внутренними компонентами JIT, однако для этого потребуется тщательное тестирование, чтобы настроить их для одного конкретного кода, на самом деле, возможно, было бы лучше избегать их полностью, особенно для тех, кто не знакомы с внутренними элементами JIT.