Машинный код виртуально
Посмотрите на нашу игру. Когда мы ее запускаем, ком-
пьютер пользователя в процессе ее выполнения не вы-
числяет множество грамматических деревьев С++.
Вместо этого, мы заранее компилируем игру в машин-
ный код, который выполняется в CPU. В чем же особен-
ность машинного кода?
Язык программирования
Ruby работал так
на протяжении 15 лет.
Только в версии 1.9 его
разработчики перешли
к использованию байт-
кода, который описыва-
ется в этой главе. Смо-
трите, сколько времени
я вам экономлю!
Если вы захотите пере-
считать самостоятельно,
не забудьте учесть ука-
затели на виртуальные
таблицы.
Более подробно о том,
что такое кэш и как он
влияет на производи-
тельность, в главе Ло-
кальность данных (Data
Locality) (с. 343).
206
Байт-код (Bytecode) —
Паттерны программирования игр
• Он компактный.
Это цельный непрерывный блок
бинарных данных, ни один бит не уходит вхолостую.
• Он линеен
. Инструкции сгруппированы и выполня-
ются одна за другой. Нет прыжков по памяти (ну,
до тех пор, пока вам не нужен поток управления).
• Он низкоуровневый
. Каждая инструкция выполняет
одну относительно простую операцию, а сложное
поведение получается путем их
комбинации
.
• Он быстрый
. Как следствие из всего вышесказан-
ного (ладно, на самом деле он просто реализован
на аппаратном уровне), машинный код выполняет-
ся со скоростью ветра.
Это звучит здорово, но мы не хотим превращать наши
заклинания в настоящий машинный код. Предоставить
пользователям машинный код, который игра будет вы-
полнять, — хм, попахивает проблемами. Нам нужно не-
что среднее между производительностью машинного кода
и безопасностью паттерна Интерпретатор (Interpreter).
А не определить ли нам собственный
виртуальный
машинный код? Для этого нам понадобится просто напи-
сать небольшой эмулятор внутри игры. Похожий на ма-
шинный код — компактный, линейный, относительно
низкоуровневый, — он будет полностью обрабатываться
игрой, так что мы сможем безопасно его изолировать.
Мы назовем наш маленький эмулятор
виртуаль-
ной машиной
(сокращенно «ВМ»), а синтетический би-
нарный машинный код, который будет выполняться, —
байт-кодом
. Он достаточно гибкий и позволяет легко
определять что-то как данные, но при этом он облада-
ет лучшей производительностью по сравнению с высо-
коуровневыми представлениями типа паттерна Интер-
претатор (Interpreter).
Моя цель до конца главы — показать вам, что задача
оказывается вполне посильной, если ограничить функцио-
нальность. Даже если вы не будете использовать паттерн,
то вы, по крайней мере, получите более глубокое понима-
ние Lua и других языков, где реализован данный подход.
Поэтому многие игро-
вые консоли и iOS
не позволяют исполнять
машинный код, загру-
женный или сгенериро-
ванный в процессе вы-
полнения. Но самые
быстрые языки програм-
мирования делают
именно так. В них
встроена компиляция
«на лету» (just-in-time —
JIT
), которая трансфор-
мирует язык в оптими-
зированный машинный
код прямо по ходу вы-
полнения.
В кругах программистов
«виртуальная машина»
и «интерпретатор» яв-
ляются синонимами
и считаются взаимоза-
меняемыми. Когда я ссы-
лаюсь на паттерн
«Банды четырех»,
я пишу именно «пат-
терн».
Do'stlaringiz bilan baham: |