Dla Pythona zaproponowano kompilator JIT, korzystający z techniki copy-and-patch

Brandt Bucher z firmy Microsoft, członek zespołu rdzennego CPython oraz pracujący nad zwiększeniem wydajności interpretera CPython, opublikował implementację kompilatora JIT dla Pythona, korzystającą z techniki Copy-and-Patch. Publikacja JIT zbiega się z okresem świąt Bożego Narodzenia, a zapowiedź napisana jest wierszem.

Proponowany JIT wyróżnia się bardzo wysoką szybkością generowania kodu, łatwością w utrzymaniu oraz pełną integracją z interpreterem. Zaproponowana metoda pozwala na automatyczne przekształcenie interpretera napisanego w języku C w kompilator JIT, bez oddzielnego tworzenia logiki generacji kodu i bez ręcznego tworzenia przedstawień assemblerowych. Przy takim podejściu naprawa błędu w interpreterze automatycznie prowadzi do usunięcia tej samej problemu w JIT, ponieważ wykorzystuje wspólny generator kodu.

Zastosowanie metody Copy-and-Patch opiera się na tym, że relokacja kodu w pamięci podczas ładowania przez linkera plików obiektowych oraz podstawienie instrukcji maszynowych zamiast bajtkodu w JIT są podobnymi zadaniami. W przypadku działania JIT w trakcie wykonywania programu przeglądane są instrukcje bajtkodu wygenerowane przez interpreter, a dla każdej instrukcji kopiowany jest wcześniej skompilowany kod maszynowy do obszaru pamięci z wykonywalnym kodem oraz na bieżąco modyfikowane są instrukcje, by wprowadzić przetwarzane dane (JIT kopiuje gotowe szablony już skompilowanych funkcji i podstawia w nich potrzebne wartości, takie jak argumenty i stałe). Przy ładowaniu plików obiektowych również wykonywane jest kopiowanie kodu maszynowego do pamięci oraz podstawienie symboli zewnętrznych.

W Copy-and-Patch JIT za pomocą LLVM tworzony jest plik obiektowy w formacie ELF, zawierający dane o instrukcjach bajtkodu oraz informacje o koniecznych zastąpieniach danych. JIT zastępuje instrukcje bajtkodu wygenerowane podczas interpretacji programu przedstawieniami kodu maszynowego, jednocześnie podstawiając dane niezbędne do obliczeń. Implementacja JIT wymaga na etapie kompilacji zależności od LLVM, jednak komponenty runtime nie są związane z zewnętrznymi zależnościami i składają się w przybliżeniu z 300 ręcznie napisanych linii w języku C oraz 3000 wygenerowanych linii kodu w C.

W porównaniu do tradycyjnych narzędzi JIT (LLVM -O0) proponowany JIT zapewnia 100 razy szybszą generację kodu i 15% szybszy kod wynikowy. W porównaniu z kompilacją do WebAssembly (Liftoff), nowy JIT generuje kod 5 razy szybciej, a kod wynikowy działa 50% szybciej. Porównując nowy JIT z optymalizującym JIT (LuaJIT), wykorzystującym ręcznie napisany kod asemblera, zaproponowana opcja była szybsza w 13 z 44 testów, a średnio ustępowała wydajnością o 35%, przy znacznym uproszczeniu konserwacji i zmniejszeniu poziomu złożoności wdrożenia.

Odtwarzaj wideo


Źródło: opennet.ru
Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster