PDA

Просмотр полной версии : [Plugin] JIT compiler



punkochel
18.11.2020, 10:51
JIT compiler

JIT compiler - это плагин, позволяющий использовать JIT-компиляцию (https://ru.wikipedia.org/wiki/JIT-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F#:~:text=JIT%2D%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F%20(%D0%B0%D0%BD%D0%B3%D0%BB.,%D0%BD%D0%B5%D0%BF%D0%BE%D1%81%D1%80%D0%B5%D0%B4%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%20%D0%B2%D0%BE%20%D0%B2%D1%80%D0%B5%D0%BC%D1%8F%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B%20%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B.) в языке программирования Pawn. Он компилирует байт-код AMX в нативный код x86 перехватывая используемые сервером SA-MP функции AMX API, который в свою очередь вызывается сервером SA-MP для замены интерпретатора виртуальной машины.

Как это работает:


Код компилируется один раз и сохраняется в памяти до выгрузки соответствующего AMX. Из-за этого при загрузке / инициализации скрипта происходит небольшая задержка.

Большая часть процесса компиляции - это прямой перевод кодов операций AMX в последовательности соответствующих машинных инструкций с использованием, по сути, гигантского оператора switch. Но есть места, где JIT-компилятор пытается быть немного умнее: например, он заменяет вызовы общих функций с плавающей точкой (те, что находятся в float.inc) эквивалентными инструкциями математического сопроцессора, встроенного в ЦП, чтобы избежать накладных расходов, а именно вызовов нативных функций.

Ограничения:



Все, что не использует #emit, вероятно, будет работать нормально. В противном случае это зависит от кода. Есть несколько продвинутых хаков #emit, которые просто не работают с этой JIT. Самомодифицирующийся код является одним из примеров;

Если вы используете библиотеку YSI (https://github.com/Y-Less/YSI), то скорее всего, плагин JIT compiler не будет работать и просто приведет к сбою вашего сервера. Однако с последними версиями YSI это может быть не так;

Плагины, которые перехватывают amx_Exec(), например CrashDetect (https://github.com/Zeex/samp-plugin-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 содержит вспомогательные функции, но для работы плагина, подключать его не обязательно.


Источники:



Скачать плагин: GitHub (https://github.com/Zeex/samp-plugin-jit/releases)

JIT-компиляция: Wikipedia (https://ru.wikipedia.org/wiki/JIT-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F#:~:text=JIT%2D%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F%20(%D0%B0%D0%BD%D0%B3%D0%BB.,%D0%BD%D0%B5%D0%BF%D0%BE%D1%81%D1%80%D0%B5%D0%B4%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%20%D0%B2%D0%BE%20%D0%B2%D1%80%D0%B5%D0%BC%D1%8F%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B%20%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B.)


Благодарности:


Daniel_Cortez (https://pro-pawn.ru/member.php?100-Daniel_Cortez), за помощь в переводе оригинальной статьи.




Автор статьи: punkochel (https://pro-pawn.ru/member.php?9227-punkochel)

Источник тестов: Мифы о Pawn-скриптинге - #7 (https://pro-pawn.ru/showthread.php?13493-%D0%9C%D0%B8%D1%84%D1%8B-%D0%BE-Pawn-%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3%D0%B5-7)

Источник материала для статьи: GitHub (https://github.com/Zeex/samp-plugin-jit)


*Исключительно для pro-pawn.ru

Копирование данной статьи на других ресурсах без разрешения автора или Daniel_Cortez (https://pro-pawn.ru/member.php?100-Daniel_Cortez) запрещено!

Salik_Davince
18.11.2020, 13:04
Опечатка в названии темы.

Daniel_Cortez
18.11.2020, 16:38
Он компилирует байт-код AMX в собственный код x86
В данном случае "native" переводится буквально как "нативный", а не "собственный".


и подключается к API AMX
"hooks into" из оригинала переводится как "перехватывает". Т.е. целиком должно получиться что-то вроде "перехватывает используемые сервером SA-MP функции AMX API".


switch оператора
Либо "switch-оператора", либо "оператора switch".


эквивалентными инструкциями FP, встроенными в ЦП
"FP" переводится как "математический сопроцессор". Т.е., целиком: "математического сопроцессора, встроенного в ЦП".


вызовов собственных функций
См. ответ к цитате #1.


Все, что не используется #emit
"не использует".


#emit приемов
В оригинале используется слово "hacks", которое как "приёмы" можно перевести разве что с большой натяжкой.
(Вообще, ИМХО, хаки всегда стоит называть своими именами, это не какой-то мега-толерантный форум).
И см. цитату #3.


Если вы используете YSI, этот плагин
Это библиотека (набор инклудов), а не плагин. Хоть эта ошибка и унаследована из оригинала (там тоже используется слово "plugin"), уверен, здесь лучше всё же исправить её.

Danich
27.11.2020, 07:25
Крэшит начиная с 2.4 версии на windows 7.


-----------------------

SA-MP Server: 0.3.7-R2



Exception At Address: 0x109804EC Module: (Unknown)



Registers:

EAX: 0x00000000 EBX: 0x075A6704 ECX: 0x64396EE1 EDX: 0x059620F0

ESI: 0x10985715 EDI: 0x00000000 EBP: 0x0018FD20 ESP: 0x0018FCC4

EFLAGS: 0x00010246



Stack:

+0000: 0x00589840 0x00000020 0x0018FCD4 0x07B30764

+0010: 0x00000000 0x00000100 0x07B30774 0x07B30764

+0020: 0x00000000 0x00000000 0x00000000 0x00000000

+0030: 0x0018FE00 0x00589840 0x10980301 0x109856D0

+0040: 0x00589840 0x02A466A8 0x00000000 0x00000000

+0050: 0x00000000 0x00000000 0x109856D0 0x0018FD34

+0060: 0x73F17A17 0x0000004C 0x0018FE00 0x0000004C

+0070: 0x0018FD50 0x73F14E31 0x0018FE00 0x0000004C

+0080: 0x0000004C 0x00589840 0x00000000 0x0018FD70

+0090: 0x6FC63484 0x00589840 0x0018FE00 0x0000004C

+00A0: 0x0000792C 0x05979DF8 0x0000004C 0x0018FD98

+00B0: 0x72AF5E81 0x00589840 0x0018FE00 0x00000000

+00C0: 0x00000001 0x05979DB0 0x00000000 0x05960920

+00D0: 0x0018FD01 0x0018FDD4 0x72AF128B 0x0018FE00

+00E0: 0x02A465B0 0x72AE1F82 0x64396F9D 0x00000001

+00F0: 0x00589840 0x00000000 0x00000001 0x05979DB0

+0100: 0x0018FDAC 0x0018FE24 0x72B09CE0 0x00000000

+0110: 0x0018FDE4 0x72AEBB3A 0x0018FE00 0x0000004C

+0120: 0x00515BF8 0x0046F654 0x00589840 0x0018FE00

+0130: 0x0000004C 0x00522850 0xFFFFFFFF 0x0000004C



--------------------------



Loaded Modules:

samp-server.exe A: 0x00400000 - 0x00519000 (C:\Games\ServNewest3\Serv\samp-server.exe)

ntdll.dll A: 0x77A90000 - 0x77C10000 (C:\Windows\SysWOW64\ntdll.dll)

kernel32.dll A: 0x76AF0000 - 0x76C00000 (C:\Windows\syswow64\kernel32.dll)

KERNELBASE.dll A: 0x76AA0000 - 0x76AE7000 (C:\Windows\syswow64\KERNELBASE.dll)

SHELL32.dll A: 0x75380000 - 0x75FCC000 (C:\Windows\syswow64\SHELL32.dll)

msvcrt.dll A: 0x76210000 - 0x762BC000 (C:\Windows\syswow64\msvcrt.dll)

SHLWAPI.dll A: 0x76690000 - 0x766E7000 (C:\Windows\syswow64\SHLWAPI.dll)

GDI32.dll A: 0x76A10000 - 0x76AA0000 (C:\Windows\syswow64\GDI32.dll)

USER32.dll A: 0x76110000 - 0x76210000 (C:\Windows\syswow64\USER32.dll)

ADVAPI32.dll A: 0x775F0000 - 0x77691000 (C:\Windows\syswow64\ADVAPI32.dll)

sechost.dll A: 0x76C60000 - 0x76C79000 (C:\Windows\SysWOW64\sechost.dll)

RPCRT4.dll A: 0x76D20000 - 0x76E10000 (C:\Windows\syswow64\RPCRT4.dll)

SspiCli.dll A: 0x751A0000 - 0x75200000 (C:\Windows\syswow64\SspiCli.dll)

CRYPTBASE.dll A: 0x75190000 - 0x7519C000 (C:\Windows\syswow64\CRYPTBASE.dll)

LPK.dll A: 0x77410000 - 0x7741A000 (C:\Windows\syswow64\LPK.dll)

USP10.dll A: 0x76C80000 - 0x76D1D000 (C:\Windows\syswow64\USP10.dll)

WSOCK32.dll A: 0x75040000 - 0x75047000 (C:\Windows\system32\WSOCK32.dll)

WS2_32.dll A: 0x76710000 - 0x76745000 (C:\Windows\syswow64\WS2_32.dll)

NSI.dll A: 0x76C00000 - 0x76C06000 (C:\Windows\syswow64\NSI.dll)

WINMM.dll A: 0x75050000 - 0x75082000 (C:\Windows\system32\WINMM.dll)

IMM32.DLL A: 0x77580000 - 0x775E0000 (C:\Windows\system32\IMM32.DLL)

MSCTF.dll A: 0x77340000 - 0x7740E000 (C:\Windows\syswow64\MSCTF.dll)

jit.DLL A: 0x73F10000 - 0x73F54000 (C:\Games\ServNewest3\Serv\plugins\jit.DLL)

MSVCP100.dll A: 0x738B0000 - 0x73919000 (C:\Windows\system32\MSVCP100.dll)

MSVCR100.dll A: 0x73020000 - 0x730DF000 (C:\Windows\system32\MSVCR100.dll)

mysql.DLL A: 0x733B0000 - 0x733FE000 (C:\Games\ServNewest3\Serv\plugins\mysql.DLL)

log-core.dll A: 0x73890000 - 0x738AC000 (C:\Games\ServNewest3\Serv\log-core.dll)

MSVCP140.dll A: 0x736E0000 - 0x7374F000 (C:\Windows\system32\MSVCP140.dll)

VCRUNTIME140.dll A: 0x74FB0000 - 0x74FC4000 (C:\Windows\system32\VCRUNTIME140.dll)

api-ms-win-crt-runtime-l1-1-0.dll A: 0x74F50000 - 0x74F54000 (C:\Windows\system32\api-ms-win-crt-runtime-l1-1-0.dll)

ucrtbase.DLL A: 0x73600000 - 0x736DF000 (C:\Windows\system32\ucrtbase.DLL)

api-ms-win-core-timezone-l1-1-0.dll A: 0x74FE0000 - 0x74FE3000 (C:\Windows\system32\api-ms-win-core-timezone-l1-1-0.dll)

api-ms-win-core-file-l2-1-0.dll A: 0x74190000 - 0x74193000 (C:\Windows\system32\api-ms-win-core-file-l2-1-0.dll)

api-ms-win-core-localization-l1-2-0.dll A: 0x74A00000 - 0x74A03000 (C:\Windows\system32\api-ms-win-core-localization-l1-2-0.dll)

api-ms-win-core-synch-l1-2-0.dll A: 0x73D60000 - 0x73D63000 (C:\Windows\system32\api-ms-win-core-synch-l1-2-0.dll)

api-ms-win-core-processthreads-l1-1-1.dll A: 0x740D0000 - 0x740D3000 (C:\Windows\system32\api-ms-win-core-processthreads-l1-1-1.dll)

api-ms-win-core-file-l1-2-0.dll A: 0x74110000 - 0x74113000 (C:\Windows\system32\api-ms-win-core-file-l1-2-0.dll)

api-ms-win-crt-heap-l1-1-0.dll A: 0x740B0000 - 0x740B3000 (C:\Windows\system32\api-ms-win-crt-heap-l1-1-0.dll)

api-ms-win-crt-string-l1-1-0.dll A: 0x740C0000 - 0x740C4000 (C:\Windows\system32\api-ms-win-crt-string-l1-1-0.dll)

api-ms-win-crt-stdio-l1-1-0.dll A: 0x73F80000 - 0x73F84000 (C:\Windows\system32\api-ms-win-crt-stdio-l1-1-0.dll)

api-ms-win-crt-convert-l1-1-0.dll A: 0x73F70000 - 0x73F74000 (C:\Windows\system32\api-ms-win-crt-convert-l1-1-0.dll)

api-ms-win-crt-locale-l1-1-0.dll A: 0x73F00000 - 0x73F03000 (C:\Windows\system32\api-ms-win-crt-locale-l1-1-0.dll)

api-ms-win-crt-filesystem-l1-1-0.dll A: 0x73E90000 - 0x73E93000 (C:\Windows\system32\api-ms-win-crt-filesystem-l1-1-0.dll)

api-ms-win-crt-time-l1-1-0.dll A: 0x73E80000 - 0x73E83000 (C:\Windows\system32\api-ms-win-crt-time-l1-1-0.dll)

api-ms-win-crt-environment-l1-1-0.dll A: 0x73880000 - 0x73883000 (C:\Windows\system32\api-ms-win-crt-environment-l1-1-0.dll)

api-ms-win-crt-math-l1-1-0.dll A: 0x73870000 - 0x73875000 (C:\Windows\system32\api-ms-win-crt-math-l1-1-0.dll)

api-ms-win-crt-utility-l1-1-0.dll A: 0x73860000 - 0x73863000 (C:\Windows\system32\api-ms-win-crt-utility-l1-1-0.dll)

api-ms-win-crt-multibyte-l1-1-0.dll A: 0x74010000 - 0x74015000 (C:\Windows\system32\api-ms-win-crt-multibyte-l1-1-0.dll)

libmariadb.dll A: 0x6FCD0000 - 0x6FD9D000 (C:\Games\ServNewest3\Serv\libmariadb.dll)

Secur32.dll A: 0x74AF0000 - 0x74AF8000 (C:\Windows\system32\Secur32.dll)

CRYPT32.dll A: 0x75FD0000 - 0x760F2000 (C:\Windows\syswow64\CRYPT32.dll)

MSASN1.dll A: 0x774C0000 - 0x774CC000 (C:\Windows\syswow64\MSASN1.dll)

NLAapi.dll A: 0x73840000 - 0x73850000 (C:\Windows\system32\NLAapi.dll)

napinsp.dll A: 0x73830000 - 0x73840000 (C:\Windows\system32\napinsp.dll)

pnrpnsp.dll A: 0x735E0000 - 0x735F2000 (C:\Windows\system32\pnrpnsp.dll)

mswsock.dll A: 0x75000000 - 0x7503C000 (C:\Windows\System32\mswsock.dll)

DNSAPI.dll A: 0x74F60000 - 0x74FA4000 (C:\Windows\system32\DNSAPI.dll)

winrnr.dll A: 0x735D0000 - 0x735D8000 (C:\Windows\System32\winrnr.dll)

rasadhlp.dll A: 0x74F00000 - 0x74F06000 (C:\Windows\system32\rasadhlp.dll)

sscanf.DLL A: 0x10000000 - 0x1000E000 (C:\Games\ServNewest3\Serv\plugins\sscanf.DLL)

streamer.DLL A: 0x6FC60000 - 0x6FCC7000 (C:\Games\ServNewest3\Serv\plugins\streamer.DLL)

YSF.DLL A: 0x028E0000 - 0x02985000 (C:\Games\ServNewest3\Serv\plugins\YSF.DLL)

OLEAUT32.dll A: 0x762F0000 - 0x76382000 (C:\Windows\syswow64\OLEAUT32.dll)

SKY.DLL A: 0x6FBE0000 - 0x6FC5D000 (C:\Games\ServNewest3\Serv\plugins\SKY.DLL)

pawncmd.DLL A: 0x72EC0000 - 0x72EF9000 (C:\Games\ServNewest3\Serv\plugins\pawncmd.DLL)

timerfix.DLL A: 0x74000000 - 0x74009000 (C:\Games\ServNewest3\Serv\plugins\timerfix.DLL)

MSVCP120.dll A: 0x6F000000 - 0x6F071000 (C:\Windows\system32\MSVCP120.dll)

MSVCR120.dll A: 0x6B760000 - 0x6B84E000 (C:\Windows\system32\MSVCR120.dll)

pawn-memory.DLL A: 0x73F90000 - 0x73F9A000 (C:\Games\ServNewest3\Serv\plugins\pawn-memory.DLL)

pawnraknet.DLL A: 0x6F220000 - 0x6F299000 (C:\Games\ServNewest3\Serv\plugins\pawnraknet.DLL)

profiler.DLL A: 0x72AE0000 - 0x72B1F000 (C:\Games\ServNewest3\Serv\plugins\profiler.DLL)

wshtcpip.dll A: 0x74FF0000 - 0x74FF5000 (C:\Windows\System32\wshtcpip.dll)

IPHLPAPI.DLL A: 0x74EE0000 - 0x74EFC000 (C:\Windows\system32\IPHLPAPI.DLL)

WINNSI.DLL A: 0x74ED0000 - 0x74ED7000 (C:\Windows\system32\WINNSI.DLL)



Здесь дамп залил (https://drive.google.com/file/d/1e2xSbk4y0K8ImfLJ2pTMeqHC_ICZtPi6/view?usp=sharing)

Сам без понятия что с этим делать) Что не сходится с 2.4 версией?