asm.js
Разработано | Мозилла |
---|---|
Впервые появился | 21 марта 2013 г [1] |
ТЫ | Независимый от платформы |
Веб-сайт | asmjs |
Под влиянием | |
JavaScript | |
Под влиянием | |
Веб-сборка |
asm.js — это подмножество JavaScript , предназначенное для запуска компьютерного программного обеспечения , написанного на таких языках, как C , как веб-приложения , сохраняя при этом характеристики производительности значительно лучше, чем стандартный JavaScript , который является типичным языком, используемым для таких приложений.
asm.js состоит из строгого подмножества JavaScript, в который код, написанный на статически типизированных языках с ручным управлением памятью (например, C), транслируется компилятором исходного кода, таким как Emscripten (на основе LLVM ). [2] Производительность повышается за счет ограничения возможностей языка теми, которые поддаются предварительной оптимизации и другим улучшениям производительности.
Mozilla Firefox был первым веб-браузером, в котором реализована оптимизация, специфичная для asm.js, начиная с версии 22. [3]
asm.js заменяется WebAssembly .
Дизайн
[ редактировать ]asm.js обеспечивает значительное повышение производительности веб-приложений , но не направлен на повышение производительности написанного вручную кода JavaScript и не обеспечивает ничего, кроме повышения производительности.
Предполагается, что характеристики производительности будут ближе к характеристикам собственного кода, чем у стандартного JavaScript, за счет ограничения возможностей языка теми, которые поддаются предварительной оптимизации и другим улучшениям производительности. [4] Благодаря использованию подмножества JavaScript asm.js в значительной степени поддерживается всеми основными веб-браузерами . [5] в отличие от альтернативных подходов, таких как Google Native Client .
Генерация кода
[ редактировать ]asm.js обычно не пишется напрямую: вместо этого, будучи промежуточным языком, он генерируется с помощью компилятора , который принимает исходный код на таком языке, как C++ , и выводит asm.js.
Например, учитывая следующий код C:
int f(int i) {
return i + 1;
}
Emscripten выведет следующий JS-код:
function f(i) {
i = i|0;
return (i + 1)|0;
}
Обратите внимание на добавление |0
и отсутствие спецификаторов типа. В JavaScript побитовые операторы преобразуют свои операнды в 32-битные целые числа со знаком и выдают целочисленные результаты. Это означает, что побитовое ИЛИ с нулем преобразует значение в целое число (очень простое «концептуальное» представление побитовых операторов может вообще не иметь дело с преобразованием типов, но каждый язык программирования определяет операторы для своего удобства, как это делает Javascript) . Делая это для каждого параметра, вы гарантируете, что если функция будет вызвана из внешнего кода, значение будет преобразовано в правильный тип. Это также используется для возвращаемого значения, в данном случае для того, чтобы гарантировать, что результатом добавления 1 к i будет целое число (так как в противном случае оно может стать слишком большим), а также для обозначения типа возвращаемого значения функции. Эти преобразования необходимы asm.js, чтобы оптимизирующий компилятор мог заранее создавать высокоэффективный собственный код. В таком оптимизирующем компиляторе никакие преобразования не выполняются, когда код asm.js вызывает другой код asm.js, поскольку требуемые спецификаторы типов означают, что значения уже будут иметь правильный тип. Более того, вместо сложения чисел с плавающей запятой и преобразования в целое число он может просто выполнить собственную целочисленную операцию. В совокупности это приводит к значительному повышению производительности.
Вот еще один пример расчета длины строки:
size_t strlen(char *ptr) {
char *curr = ptr;
while (*curr != 0) {
curr++;
}
return (curr - ptr);
}
В результате получится следующий код asm.js:
function strlen(ptr) {
ptr = ptr|0;
var curr = 0;
curr = ptr;
while ((MEM8[curr>>0]|0) != 0) {
curr = (curr + 1)|0;
}
return (curr - ptr)|0;
}
В сгенерированном коде переменная MEM8 фактически представляет собой побайтовое «представление» типизированного буфера, который служит «кучей» кода asm.js.
Производительность
[ редактировать ]Поскольку asm.js запускается в браузере, производительность сильно зависит как от браузера, так и от оборудования. Предварительные тесты программ на C, скомпилированных в asm.js, обычно в два раза медленнее, чем собственная компиляция с помощью Clang . [6]
Во многом этот прирост производительности по сравнению с обычным JavaScript обусловлен 100%-ной согласованностью типов и практически отсутствием сборки мусора (управление памятью осуществляется вручную в большом типизированном массиве). Эта более простая модель без динамического поведения, выделения или освобождения памяти, а только узкий набор четко определенных операций с целыми числами и числами с плавающей запятой обеспечивает гораздо большую производительность и потенциал для оптимизации . [ нужна ссылка ]
Тест Mozilla от декабря 2013 года показал значительные улучшения: «Firefox с оптимизацией float32 может запускать все эти тесты примерно в 1,5 раза медленнее, чем нативные, или лучше». [7] Mozilla отмечает, что производительность скомпилированного в собственном коде кода — это не один показатель, а скорее диапазон, при этом разные собственные компиляторы (в данном случае Clang и GCC ) предоставляют код с разной производительностью. «На самом деле, в некоторых тестах, таких как Box2D , FASTA и копирование, asm.js настолько же близок или ближе к Clang, чем Clang к GCC. В одном случае asm.js даже немного превосходит Clang на Box2D». [7]
Реализации
[ редактировать ]Проект Emscripten предоставляет инструменты, которые можно использовать для компиляции кодовых баз C и C++ (или любых других языков, которые можно преобразовать в LLVM IR ) в asm.js. [2]
Все браузеры с поддержкой ECMAScript 6 должны иметь возможность запускать код asm.js, поскольку он является подмножеством этой спецификации. Однако, поскольку в эту редакцию были добавлены функции, обеспечивающие полную поддержку asm.js ( Math.fround()
), в старых браузерах, в которых отсутствуют эти функции, могут возникнуть проблемы.
Некоторые реализации браузеров специально оптимизированы для asm.js:
- Mozilla Firefox был первым веб-браузером, в котором реализована оптимизация, специфичная для asm.js, начиная с Firefox 22. [3] OdinMonkey , современный компилятор asm.js от Mozilla, используемый в Firefox, является компонентом IonMonkey , JIT-компилятора SpiderMonkey .
- Microsoft реализовала поддержку asm.js в Chakra , движке JavaScript, используемом Microsoft Edge Legacy , выполняя проверку для создания высокооптимизированного JIT-кода. [8]
- Оптимизация JavaScript-движка Google Chrome V8 в Chrome 28 позволила выполнять тесты asm.js более чем в два раза быстрее, чем в предыдущих версиях Chrome. [9] хотя Chrome V8 не использует предварительную компиляцию.
Принятие
[ редактировать ]Почти все текущие приложения, основанные на asm.js, представляют собой приложения C/C++, скомпилированные в asm.js с использованием Emscripten или Mandreel. Имея это в виду, в ближайшем будущем на asm.js будут ориентироваться те приложения, которые выиграют от переносимости работы в браузере, но имеют уровень сложности, для которого прямой порт на JavaScript был бы целесообразным. невыполнимо.
языков программирования , фреймворков приложений , программ , библиотек , игр , игровых движков На данный момент уже портирован ряд и другого программного обеспечения . [10] Некоторые из них приведены ниже.
Языки программирования
[ редактировать ]- C/C++ : Clang и LLVM
- Rust : нацелен на Emscripten
- Perl : порт (микро)perl-5.16.3. [11]
- Python – порт CPython [12]
- Руби – порт Руби [13]
Платформы приложений
[ редактировать ]- Pepper.js: порты различных приложений PNaCl (земля, вороной, пуля и т. д.). [14]
- Qt : порты различных демонстраций Qt, а также приложений KDE, таких как Kate. [15]
Программы и библиотеки
[ редактировать ]- OpenGL , SDL и SDL2. [16]
- Вим (Vi улучшенный) [17]
- FreeType : TrueType рендеринг шрифтов в JavaScript с использованием FreeType. [18]
- SQLite [19]
- Защита конфиденциальности GNU [20]
- ctags [21]
- сорванный [22]
- графвиз [23]
- zlib [24]
Игровые движки
[ редактировать ]- Unreal Engine 3 : портировали за 4 дня [25] [26]
- Нереальный Движок 4
- Единство [27]
- ScummVM , поддерживающий множество классических приключенческих игр. [28]
- Годо [29]
Игры
[ редактировать ]- Doom : игровые ресурсы Freedoom с открытым исходным кодом, работающие на PrBoom и основанные на коде Doom с открытым исходным кодом. [30]
- СуперТукс [31]
- Дюна II через OpenDune [32]
- Банановый хлеб на основе Cube 2 [33]
- Все игры из Humble Mozilla Bundle. [34] ( Super Hexagon , AaAaAA! for the Awesome , Osmos , Zen Bound 2 , Dustforce DX , Voxatron , FTL: Advanced Edition и Democracy 3 )
Эмуляторы
[ редактировать ]- EM-DOSBox: порт DOSBox на Emscripten. [35]
- Start9.io : платформа веб-эмуляции, ориентированная на несколько игровых архитектур.
- JSMESS: порт эмулятора MESS для многих игровых консолей и компьютерных систем. [36]
Математика
[ редактировать ]- HTML5 фрактальная площадка [37] , генерируемые итерационной функцией – рисует фракталы , такие как множество Мандельброта .
Устаревание
[ редактировать ]asm.js по большей части устарел с появлением WebAssembly (wasm), который имеет формат байт-кода, который быстрее анализируется. [38] Попытки расширить JavaScript за счет более низкоуровневых функций, таких как SIMD.js, также были приостановлены с 2017 года. [39]
asm.js остается полезным в первую очередь как «запасной вариант» для wasm благодаря программе, написанной организацией WebAssembly, которая преобразует wasm в asm.js. Специального конвертера asm.js в Wasm не существует, но TypeScript -to-wasm. частично можно использовать компиляторы [40] Ссылочный двоичный эмиттер WebAssembly, используемый для хранения asm2wasm
модуль, но он был удален после того, как Emscripten перестал его использовать. [41]
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ «asm.js в Firefox Nightly» . Блог Люка Вагнера . 21 марта 2013 г. Проверено 13 ноября 2014 г.
- ^ Jump up to: а б «kripken/emscripten · GitHub» . Гитхаб.com . Проверено 05 марта 2015 г.
- ^ Jump up to: а б «Примечания к выпуску Firefox 22.0» . Мозилла . Проверено 4 июля 2013 г.
- ^ «Асм.js» . Асм.js. Проверено 05 марта 2015 г.
- ^ «asm.js — часто задаваемые вопросы» . Asmjs.org. 26 июля 2014 г.
- ^ "asm.js" . Асм.js. Проверено 05 марта 2015 г.
- ^ Jump up to: а б Алон Закаи; Роберт Найман (20 декабря 2013 г.). «Разрыв между производительностью asm.js и нативной производительностью становится еще меньше благодаря оптимизации float32» . Проверено 11 апреля 2014 г.
- ^ «Внедрение Asm.js в Chakra и Microsoft Edge» . Майкрософт. 7 мая 2015 г. Проверено 7 мая 2015 г.
- ^ «Chrome 28 Beta: более захватывающий Интернет повсюду» . Google . Проверено 6 июля 2013 г.
- ^ «Главная — Демо — Игры и игровые движки» .
- ^ «плю» . Themucker.github.io. Архивировано из оригинала 3 августа 2013 г. Проверено 05 марта 2015 г.
- ^ «repl.it — Python» . Репл.ит. Проверено 05 марта 2015 г.
- ^ "repl.it — Рубин" . Репл.ит. Проверено 05 марта 2015 г.
- ^ «Примеры pepper.js» . Trypepperjs.appspot.com. Архивировано из оригинала 14 февраля 2020 г. Проверено 05 марта 2015 г.
- ^ «emscripten-qt — Демо» . Vps.etotheipiplusone.com. Архивировано из оригинала 13 февраля 2015 г. Проверено 05 марта 2015 г.
- ^ «Об Эмскриптене» .
- ^ «Vim.js — JavaScript-порт Vim» . Coolwanglu.github.io . Проверено 05 марта 2015 г.
- ^ «Шрифты TrueType в JavaScript» . Архивировано из оригинала 12 октября 2012 г.
- ^ «Порт SQLite на Javascript» . Гитхаб.com . Проверено 05 марта 2015 г.
- ^ «GnuPG.js» . Manuuels.github.io . Проверено 05 марта 2015 г.
- ^ «ctags в браузере» . Гитхаб.com . Проверено 05 марта 2015 г.
- ^ «Гнуплот онлайн» . Gnuplot.respawned.com. Архивировано из оригинала 22 февраля 2015 г. Проверено 05 марта 2015 г.
- ^ «Хак для размещения GraphViz в Интернете» . Гитхаб.com . Проверено 05 марта 2015 г.
- ^ «JavaScript-порт ZLib DEFLATE для браузера» . Гитхаб.com . Проверено 05 марта 2015 г.
- ^ «Epic Games выпускает в сети «Epic Citadel»» . UnrealEngine.com (пресс-релиз). 2 мая 2013. Архивировано из оригинала 30 ноября 2016 года . Проверено 24 октября 2014 г.
- ^ «Unreal Engine 3, портированный на JavaScript и WebGL, работает в любом современном браузере» . ЭкстримТех . Зифф Дэвис . Проверено 05 марта 2015 г.
- ^ «О будущем веб-публикаций в Unity» . Блоги.unity3d.com. 29 апреля 2014 г.
- ^ «HTML5» . Clb.demon.fi. Архивировано из оригинала 06 марта 2015 г. Проверено 05 марта 2015 г.
- ^ «Компиляция для Интернета» . godoengine.org . 10 ноября 2016 г.
- ^ «Код, сгенерированный Emscripten» . Крипкен.github.io . Проверено 05 марта 2015 г.
- ^ «Код, сгенерированный Emscripten» . Forandom.github.io . Проверено 05 марта 2015 г.
- ^ Гурьянов Александр. «Дюна 2 — Онлайн (браузерная версия)» . Эпикпорт . Проверено 05 марта 2015 г.
- ^ «Демо-версия бананового хлеба Mozilla» . Developer.mozilla.org . Проверено 05 марта 2015 г.
- ^ «Humble Mozilla Bundle продвигает браузерные игры на базе WebGL» . Арс Техника. 15 октября 2014 г. Проверено 15 октября 2014 г.
- ^ «EM-Dosbox на Github» . Проверено 9 апреля 2015 г.
- ^ «Перенаправление страницы» . Jsmess.textfiles.com . Проверено 05 марта 2015 г.
- ^ «Фрактальная площадка HTML5» . Danielsadvernture.info. Архивировано из оригинала 22 февраля 2015 г. Проверено 05 марта 2015 г.
- ^ "ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ" . Веб-сборка .
- ^ «Предложение TC39 для SIMD.js» . Экма TC39. 23 июня 2020 г.
- ^ «WebAssembly/двоичный файл» . Гитхаб . Веб-сборка. 25 июня 2020 г.
AssemblyScript, который компилирует TypeScript в Binaryen IR; Wasm2js, который компилирует WebAssembly в JS.
- ^ «Журнал изменений Binaryen» . Гитхаб .
v97: Удалить asm2wasm, который поддерживал серверную часть fastcomp Emscripten, после удаления fastcomp.
(См. также PR#3042 .)