JIT compiler
JIT compiler - это плагин, позволяющий использовать JIT-компиляцию в языке программирования Pawn. Он компилирует байт-код AMX в нативный код x86 перехватывая используемые сервером SA-MP функции AMX API, который в свою очередь вызывается сервером SA-MP для замены интерпретатора виртуальной машины.
Как это работает:
Код компилируется один раз и сохраняется в памяти до выгрузки соответствующего AMX. Из-за этого при загрузке / инициализации скрипта происходит небольшая задержка.
Большая часть процесса компиляции - это прямой перевод кодов операций AMX в последовательности соответствующих машинных инструкций с использованием, по сути, гигантского оператора switch. Но есть места, где JIT-компилятор пытается быть немного умнее: например, он заменяет вызовы общих функций с плавающей точкой (те, что находятся в float.inc) эквивалентными инструкциями математического сопроцессора, встроенного в ЦП, чтобы избежать накладных расходов, а именно вызовов нативных функций.
Ограничения:
- Все, что не использует #emit, вероятно, будет работать нормально. В противном случае это зависит от кода. Есть несколько продвинутых хаков #emit, которые просто не работают с этой JIT. Самомодифицирующийся код является одним из примеров;
- Если вы используете библиотеку YSI, то скорее всего, плагин JIT compiler не будет работать и просто приведет к сбою вашего сервера. Однако с последними версиями YSI это может быть не так;
- Плагины, которые перехватывают amx_Exec(), например CrashDetect, не могут использоваться вместе с этим плагином. Если такой перехватчик обнаружен, вы получите сообщение об ошибке при запуске, и ваш код будет запускаться через интерпретатор по умолчанию, как обычно.
Тесты производительности (сравнение):
Открыть/закрыть
Настройки профайлера:
/*======== Настройки =========================================================*/
// Кол-во итераций в циклах.
const PROFILER_ITERATIONS_MAJOR = 10_000;
const PROFILER_ITERATIONS_MINOR = 100;
// Названия отрывков кода.
new const code_snippets_names[2][] =
{
{"native function"},
{"Pawn function"}
};
#include <core>
LowerCase0(string[])
{
static pos;
for (pos = -1; string[++pos] != '\0';)
string
[pos
] = tolower(string
[pos
]);
}
LowerCase1(string[])
{
static pos, c;
for (pos = 0; ; ++pos)
{
if (0 != (c = string[pos]))
{
if (c < 'A')
continue;
if ('Z' < c)
continue;
string[pos] = c + ('a' - 'A');
continue;
}
break;
}
}
#define Prerequisites();\
static string[] = "ABCabcAABBCCaabbccXYZxyzXXYYZZxxyyzz";
#define CodeSnippet0();\
LowerCase0(string);
#define CodeSnippet1();\
LowerCase1(string);
/*======== Конец настроек ====================================================*/
Результаты:
Код:
Тестирование: <native function> vs <Pawn function>
Режим: интерпретируемый, 10000x100 итераций.
native function: 8001
Pawn function: 2263
Код:
Тестирование: <native function> vs <Pawn function>
Режим: с JIT-компиляцией, 10000x100 итераций.
native function: 5072
Pawn function: 213
Установка и использование:
- Скачайте плагин со страницы Releases на github (см. ниже);
- Извлеките файл jit.dll (для windows), или jit.so (для linux) в папку plugins вашего сервера;
- Подключите данный плагин в файле server.cfg в строке pluguns (обычно в самом начале);
- Запустите сервер, и если при загрузке плагина не возникло ошибок, то ваш код работает с JIT.
*Примечание: файл jit.inc содержит вспомогательные функции, но для работы плагина, подключать его не обязательно.
Источники:
Благодарности:
Автор статьи: punkochel
Источник тестов: Мифы о Pawn-скриптинге - #7
Источник материала для статьи: GitHub
*Исключительно для pro-pawn.ru
Копирование данной статьи на других ресурсах без разрешения автора или Daniel_Cortez запрещено!