Эмулятор Game Boy от студента обгоняет нативный интерпретатор, JIT-ясь в WebAssembly

WATaBoy на лету компилирует инструкции процессора Game Boy в WebAssembly, а дальше браузер сам JIT-ит этот Wasm до машинного кода. На Pokemon Blue двойная трансляция обходит нативный C-интерпретатор примерно в 1,2 раза.

Вкратце

Фокус во втором слое. WATaBoy выдаёт байткод WebAssembly для горячего кода игры, а движок Safari сам компилирует этот Wasm в нативный машинный код — так эмулятор едет на JIT браузера, а не борется с ним.

Системный инженер в треде сдул сенсацию арифметикой: накладные расходы Wasm — около 20 процентов, у цикла интерпретатора — около 1000. Обогнать интерпретатор никогда и не было сложным. Новизна в том, что JIT-рантайм для Game Boy вообще существует.

Двухслойный JIT, который превращает браузер в компилятор

Эмулятор WATaBoy с Pokemon в браузере
Эмулятор WATaBoy с Pokemon в браузере

WATaBoy — выпускной проект студента-старшекурсника с нарочно странной архитектурой: вместо того чтобы интерпретировать инструкции Game Boy по одной, он переводит их в байткод WebAssembly прямо во время работы. Сам нативный машинный код он не генерирует. Это делает JS/Wasm-движок браузера: берёт свежесгенерированный Wasm и JIT-компилирует его так же, как горячую функцию на JavaScript.

Выигрыш виден в бенчмарках. На Pokemon Blue путь JIT-в-Wasm оказался примерно в 1,2 раза быстрее нативного интерпретатора и примерно в 1,5 раза быстрее Wasm-интерпретатора. Лучшие цифры среди браузеров показал Safari, причём без всякой подстройки под конкретный браузер. Автор объясняет, почему слой косвенности выигрывает: «мы выигрываем от JIT, несмотря на то что находимся ещё на один слой косвенности дальше от нативного машинного кода».

Настоящий мотив — политика платформ. Эмуляторы вроде Dolphin не могут выйти на iOS, потому что Apple запрещает JIT-компиляцию во время работы везде, кроме браузеров, где JavaScriptCore разрешено компилировать горячий код в нативный. Прогони сгенерированный код эмулятора через Wasm во вкладке браузера, и получишь тот самый JIT, который Apple иначе запрещает.

График бенчмарка: JIT-в-Wasm против интерпретаторов
График бенчмарка: JIT-в-Wasm против интерпретаторов

Тред: «конечно он обгоняет интерпретатор, но это не самое крутое»

Заголовок читается как парадокс; инженер в треде свёл его к простой арифметике.

«Конечно он обгоняет нативный интерпретатор. Накладные расходы WASM — около 20%, у интерпретатора — около 1000%. Крутость тут в том, что JIT-рантайм для GameBoy вообще существует.» — инженер, подставивший цифры к накладным расходам

По-настоящему интересной находкой для нескольких читателей оказалась сама лазейка на iOS.

«У Apple есть одно исключение из запретов на JIT: браузеры… если JS-функцию вызвать достаточно много раз, в итоге её оптимизируют и скомпилируют в нативный машинный код. То же верно и для WebAssembly… Какой красивый способ обойти ограничения.» — bawolff, контрибьютор MediaWiki

У подхода есть родословная. Выпускник мехатроники из Ватерлоо вспомнил попытку Эндрю Келли 2013 года статически перекомпилировать код NES, которая застряла на рукописном ассемблере, не ложившемся чисто на LLVM IR. В выводах той работы говорилось, что путь — это JIT, перекомпилирующий горячие участки, когда уже есть данные времени выполнения.

«В заключении он прямо называет JIT-подход, вероятно, верным путём: ты вживую перекомпилируешь горячие участки, когда у тебя есть данные времени выполнения, нужные, чтобы их по-настоящему понять… Очень здорово увидеть такое в деле.» — инженер, следивший за работой Келли по статической перекомпиляции

Не все приняли посыл. Один комментатор указал на StikDebug, инструмент для включения JIT на iOS без обходного пути через браузер, и заметил, что заявленная мотивация проекта игнорирует уже готовое решение. И вечное напоминание: быстро-в-браузере — это не быстро-на-железе. Любитель ретро-эмуляции отметил, что нативно написанный эмулятор всё ещё работает быстрее на Pentium 166 МГц, чем этот на Core Ultra i9: налог Wasm реален, даже когда тот выигрывает дуэль, в которой его меряли.

Получайте такие разборы каждый день

Главные истории Hacker News — на email, в Telegram или RSS.

Следующая новость · 23 из 27 Читать дальше
🚀Tech

NixOS 26.05 собрали 2842 контрибьютора — а рост популярности тихо двигают LLM

NixOS 26.05 «Yarara» вышел с 59 703 коммитами с прошлого релиза и 17 532 пакетами, удалёнными намеренно. В треде новообращённые один за другим называют одну и ту же неожиданную точку входа: LLM, который наконец умеет читать и писать их конфиг.

★ 95 · 💬 79 · nixos.org · 3 мин