asm.js - это подмножество JavaScript, разработанное для того, чтобы компьютерное программное обеспечение, написанное на таких языках, как C, могло запускаться как веб-приложения , сохраняя при этом характеристики производительности значительно лучше, чем стандартный JavaScript , который является типичным языком, используемым для таких приложений.
Разработано | Mozilla |
---|---|
Впервые появился | 21 марта 2013 г . [1] |
Операционные системы | Независимая платформа |
Веб-сайт | asmjs |
Под влиянием | |
JavaScript | |
Под влиянием | |
WebAssembly |
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 я ) { вернуть я + 1 ; }
Emscripten выведет следующий JS-код:
функция f ( i ) { i = i | 0 ; возврат ( i + 1 ) | 0 ; }
Обратите внимание на добавление |0
и отсутствие спецификаторов типов. В JavaScript побитовые операторы преобразуют свои операнды в 32-разрядные целые числа со знаком и выдают целочисленные результаты. Это означает, что побитовое ИЛИ с нулем преобразует значение в целое число (очень простое «концептуальное» представление побитовых операторов может вообще не иметь дело с преобразованием типов, но каждый язык программирования определяет операторы для собственного удобства, как это делает здесь Javascript) . Выполняя это для каждого параметра, это гарантирует, что если функция вызывается из внешнего кода, значение будет преобразовано в правильный тип. Это также используется в возвращаемом значении, в данном случае, чтобы гарантировать, что результат добавления 1 к i будет целым числом (в противном случае оно может стать слишком большим), и чтобы отметить тип возвращаемого значения функции. Эти преобразования требуются asm.js, чтобы оптимизирующий компилятор мог заранее создать высокоэффективный собственный код. В таком оптимизирующем компиляторе преобразования не выполняются, когда код asm.js вызывает другой код asm.js, поскольку требуемые спецификаторы типа означают, что гарантировано, что значения уже будут иметь правильный тип. Кроме того, вместо того, чтобы выполнять сложение с плавающей запятой и преобразовывать в целое число, он может просто выполнять собственную целочисленную операцию. Вместе это приводит к значительному увеличению производительности.
Вот еще один пример расчета длины строки:
size_t strlen ( char * ptr ) { char * curr = ptr ; в то время как ( * curr ! = 0 ) { curr ++ ; } return ( curr - ptr ); }
В результате получится следующий код asm.js:
функция strlen ( ptr ) { ptr = ptr | 0 ; var curr = 0 ; curr = ptr ; в то время как (( 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 и copy, 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 , опережающий компилятор Mozilla asm.js, используемый в Firefox, является компонентом IonMonkey , JIT-компилятора SpiderMonkey .
- Microsoft реализует поддержку asm.js в Chakra , движке JavaScript, используемом Microsoft Edge , выполняя проверку для создания высокооптимизированного JIT-кода. [8]
- Оптимизации из Google Chrome «s двигатель V8 JavaScript в Chrome 28 из asm.js тестов более чем в два раза быстрее, чем предыдущие версии Chrome, [9] , хотя V8 Chrome не использует вперед-в-время компиляции.
Принятие
Почти все текущие приложения, основанные на asm.js, представляют собой приложения C / C ++, скомпилированные в asm.js с использованием Emscripten или Mandreel. Имея это в виду, приложения, которые в ближайшем будущем будут нацелены на asm.js, - это те, которые выиграют от переносимости работы в браузере, но имеют такой уровень сложности, для которого прямой перенос на JavaScript будет невыполнимо.
На данный момент уже перенесен ряд языков программирования , фреймворков , программ , библиотек , игр , игровых движков и другого программного обеспечения . [10] Некоторые из них приведены ниже.
Языки программирования
- C / C ++ : Clang и LLVM
- Rust : нацелен на Emscripten
- Lua VM: виртуальная машина Lua [11]
- Perl : порт (микро) perl-5.16.3 [12]
- Python - порт CPython [13]
- Ruby - порт Ruby [14]
Фреймворки приложений
- Pepper.js: Порты различных приложений PNaCl (earth, voronoi, bullet и т. д.) [15]
- Qt : порты различных демонстраций Qt, а также приложений KDE, таких как Kate [16]
Программы и библиотеки
- OpenGL , SDL и SDL2 [17]
- Vim (подтверждено Vi) [18]
- FreeType : рендеринг шрифтов TrueType в JavaScript с использованием FreeType [19]
- SQLite [20]
- GNU Privacy Guard [21]
- ctags [22]
- gnuplot [23]
- Графвиз [24]
- zlib [25]
Игровые движки
- Unreal Engine 3 : портировали за 4 дня [26] [27]
- Unreal Engine 4
- Единство [28]
- ScummVM , поддерживающий множество классических приключенческих игр [29]
- Годо [30]
Игры
- Дум : с открытым исходным кодом Freedoom игровые активыработающие на PrBoom , который основан на открытом исходном коде Гибели [31]
- SuperTux [32]
- Dune II через OpenDune [33]
- BananaBread на основе Куба 2 [34]
- Каждая игра из Humble Mozilla Bundle [35] ( Super Hexagon , AaAaAA! Для Awesome , Osmos , Zen Bound 2 , Dustforce DX , Voxatron , FTL: Advanced Edition и Democracy 3 )
Эмуляторы
- EM-DOSBox: порт Emscripten для DOSBox [36]
- Start9.io : платформа веб-эмуляции, ориентированная на несколько игровых архитектур.
- JSMESS: порт эмулятора MESS для многих игровых консолей и компьютерных систем [37]
Математика
- HTML5 Fractal Playground [38] - рисует фракталы , сгенерированные функцией итераций , такие как множество Мандельброта .
Устаревание
asm.js в основном устарел с появлением WebAssembly (wasm), который имеет формат байт-кода, который быстрее анализируется. [39] Попытки расширить JavaScript с помощью более низкоуровневых функций, таких как SIMD.js, также были приостановлены с 2017 года. [40]
asm.js остается полезным в первую очередь как «запасной вариант» для wasm через программу, написанную организацией WebAssembly, которая преобразует wasm в asm.js. Специального конвертера из asm.js в wasm не существует, но компиляторы TypeScript -to-wasm могут частично использоваться. [41] Ссылочный двоичный файл эмиттера WebAssembly раньше содержал asm2wasm
модуль, но он был удален после того, как Emscripten прекратил его использовать. [42]
Смотрите также
- CrossBridge
- Emscripten
- Собственный клиент Google (NaCl)
- RPython
- WebAssembly - байт-код для браузеров, предназначенный для более быстрого синтаксического анализа, чем asm.js
Рекомендации
- ^ «asm.js в Firefox Nightly» . Блог Люка Вагнера . 21 марта 2013 . Проверено 13 ноя 2014 .
- ^ а б "kripken / emscripten · GitHub" . Github.com . Проверено 5 марта 2015 .
- ^ а б «Примечания к выпуску Firefox 22.0» . Mozilla . Проверено 4 июля 2013 года .
- ^ "Asm.js" . Asm.js . Проверено 5 марта 2015 .
- ^ «asm.js - часто задаваемые вопросы» . Asmjs.org. 26 июля 2014 г.
- ^ "asm.js" . Asm.js . Проверено 5 марта 2015 .
- ^ а б Алон Закай; Роберт Найман (20 декабря 2013 г.). «Разрыв между производительностью asm.js и собственной производительностью становится еще меньше с оптимизацией float32» . Проверено 11 апреля 2014 года .
- ^ «Перенос Asm.js в Chakra и Microsoft Edge» . Microsoft. 7 мая 2015 года . Проверено 7 мая 2015 года .
- ^ «Chrome 28 Beta: более захватывающий Интернет повсюду» . Google . Проверено 6 июля 2013 .
- ^ «Главная - Демоверсии - Игры и игровые движки» .
- ^ «Lua REPL» . Kripken.github.io. Архивировано из оригинала на 2013-06-08 . Проверено 5 марта 2015 .
- ^ "плю" . Themucker.github.io. Архивировано из оригинала на 2013-08-03 . Проверено 5 марта 2015 .
- ^ "repl.it - Python" . Repl.it . Проверено 5 марта 2015 .
- ^ "repl.it - Ruby" . Repl.it . Проверено 5 марта 2015 .
- ^ "Примеры pepper.js" . Trypepperjs.appspot.com . Проверено 5 марта 2015 .
- ^ "emscripten-qt - Демо" . Vps.etotheipiplusone.com . Проверено 5 марта 2015 .
- ^ «О Эмскриптене» .
- ^ «Vim.js - JavaScript-порт Vim» . Coolwanglu.github.io . Проверено 5 марта 2015 .
- ^ «Шрифты TrueType в JavaScript» . Архивировано из оригинала на 2012-10-12.
- ^ «Порт SQLite на Javascript» . Github.com . Проверено 5 марта 2015 .
- ^ "GnuPG.js" . Manuuels.github.io . Проверено 5 марта 2015 .
- ^ "ctags в браузере" . Github.com . Проверено 5 марта 2015 .
- ^ «Гнуплот онлайн» . Gnuplot.respawned.com . Проверено 5 марта 2015 .
- ^ «Уловка для размещения GraphViz в сети» . Github.com . Проверено 5 марта 2015 .
- ^ "JavaScript-порт ZLib DEFLATE для браузера" . Github.com . Проверено 5 марта 2015 .
- ^ «Epic Games выпускает« Эпическую цитадель »в Интернете» . UnrealEngine.com (пресс-релиз). 2 мая 2013 г. Архивировано из оригинального 30 ноября 2016 года . Проверено 24 октября 2014 года .
- ^ «Unreal Engine 3, портированный на JavaScript и WebGL, работает в любом современном браузере» . ExtremeTech . Зифф Дэвис . Проверено 5 марта 2015 .
- ^ «О будущем веб-публикации в Unity» . Blogs.unity3d.com. 29 апреля 2014 г.
- ^ «HTML5» . Clb.demon.fi. Архивировано из оригинала на 2015-03-06 . Проверено 5 марта 2015 .
- ^ «Компиляция для Интернета» . godotengine.org . 10 ноября 2016 г.
- ^ «Код, созданный Emscripten» . Kripken.github.io . Проверено 5 марта 2015 .
- ^ «Код, созданный Emscripten» . Forandom.github.io . Проверено 5 марта 2015 .
- ^ Гурьянов Александр. «Дюна 2 - Онлайн (браузерная версия)» . Эпикпорт . Проверено 5 марта 2015 .
- ^ "Mozilla Banana Bread Demo" . Developer.mozilla.org . Проверено 5 марта 2015 .
- ^ «Humble Mozilla Bundle продвигает браузерные игры на базе WebGL» . Ars Technica. 15 октября 2014 . Дата обращения 15 октября 2014 .
- ^ «EM-Dosbox на Github» . Проверено 9 апреля 2015 .
- ^ «Перенаправление страниц» . Jsmess.textfiles.com . Проверено 5 марта 2015 .
- ^ «HTML5 Fractal Playground» . Danielsadvernture.info. Архивировано из оригинала на 2015-02-22 . Проверено 5 марта 2015 .
- ^ «FAQ» . WebAssembly .
- ^ «Предложение TC39 для SIMD.js» . Ecma TC39. 23 июня 2020.
- ^ «WebAssembly / binaryen» . GitHub . WebAssembly. 25 июня 2020 г.
AssemblyScript, который компилирует TypeScript в Binaryen IR; wasm2js, который компилирует WebAssembly в JS
- ^ "Журнал изменений Binaryen" . GitHub .
v97: Удалите asm2wasm, который поддерживал серверную часть fastcomp Emscripten, после удаления fastcomp.
(См. Также PR # 3042. )
Внешние ссылки
- Официальный веб-сайт