stringtranslate.com

asm.js

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-код:

функция 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 ; while ( * curr != 0 ) { curr ++ ; } return ( curr - ptr ); }                  

Это приведет к следующему коду asm.js:

функция 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, обычно в пределах 2 раз медленнее, чем нативная компиляция с 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:

Принятие

Почти все текущие приложения на основе asm.js — это приложения C/C++, скомпилированные в asm.js с помощью Emscripten или Mandreel. Учитывая это, приложения, которые в ближайшем будущем будут нацелены на asm.js, — это те, которые выиграют от переносимости работы в браузере, но имеют уровень сложности, для которого прямой перенос на JavaScript будет невозможен.

На сегодняшний день уже перенесено множество языков программирования , прикладных фреймворков , программ , библиотек , игр , игровых движков и другого программного обеспечения . [10] Некоторые из них приведены ниже.

Языки программирования

Прикладные фреймворки

Программы и библиотеки

Игровые движки

Игры

Эмуляторы

Математика

Устаревание

asm.js в основном устарел с появлением WebAssembly (wasm), который имеет формат байт-кода, который быстрее анализируется. [38] Попытки расширить JavaScript более низкоуровневыми функциями, такими как SIMD.js, также были приостановлены с 2017 года. [39]

asm.js остается полезным в первую очередь как «запасной вариант» для wasm, через программу, написанную организацией WebAssembly, которая преобразует wasm в asm.js. Не существует специального конвертера из asm.js в wasm, но компиляторы TypeScript в wasm могут быть частично использованы. [40] Ссылка на WebAssembly emitter binaryen использовалась для содержания asm2wasmмодуля, но была удалена после того, как Emscripten прекратил его использовать. [41]

Смотрите также

Ссылки

  1. ^ "asm.js в Firefox Nightly". Блог Люка Вагнера . 21 марта 2013 г. Получено 13 ноября 2014 г.
  2. ^ ab "kripken/emscripten · GitHub". Github.com . Получено 2015-03-05 .
  3. ^ ab "Заметки о выпуске Firefox 22.0". Mozilla . Получено 4 июля 2013 г. .
  4. ^ "Asm.js". Asm.js . Получено 2015-03-05 .
  5. ^ "asm.js — часто задаваемые вопросы". Asmjs.org. 26 июля 2014 г.
  6. ^ "asm.js". Asm.js . Получено 2015-03-05 .
  7. ^ ab Алон Закай; Роберт Найман (20 декабря 2013 г.). «Разрыв между asm.js и собственной производительностью становится еще меньше с оптимизацией float32» . Получено 11 апреля 2014 г.
  8. ^ «Внедрение Asm.js в Chakra и Microsoft Edge». Microsoft. 7 мая 2015 г. Получено 7 мая 2015 г.
  9. ^ "Chrome 28 Beta: более захватывающий веб, везде". Google . Получено 2013-07-06 .
  10. ^ "Главная — Демоверсии — Игры и игровые движки".
  11. ^ "plu". Themucker.github.io. Архивировано из оригинала 2013-08-03 . Получено 2015-03-05 .
  12. ^ "repl.it — Python". Repl.it . Получено 2015-03-05 .
  13. ^ "repl.it — Ruby". Repl.it . Получено 2015-03-05 .
  14. ^ "Примеры pepper.js". Trypepperjs.appspot.com. Архивировано из оригинала 2020-02-14 . Получено 2015-03-05 .
  15. ^ "emscripten-qt — Demos". Vps.etotheipiplusone.com. Архивировано из оригинала 2015-02-13 . Получено 2015-03-05 .
  16. ^ "О Emscripten".
  17. ^ "Vim.js — JavaScript-порт Vim". Coolwanglu.github.io . Получено 2015-03-05 .
  18. ^ "Шрифты TrueType в JavaScript". Архивировано из оригинала 2012-10-12.
  19. ^ "Порт SQLite в Javascript". Github.com . Получено 2015-03-05 .
  20. ^ "GnuPG.js". Manuuels.github.io . Получено 2015-03-05 .
  21. ^ "ctags в браузере". Github.com . Получено 2015-03-05 .
  22. ^ "Gnuplot online". Gnuplot.respawned.com. Архивировано из оригинала 2015-02-22 . Получено 2015-03-05 .
  23. ^ "Хак для размещения GraphViz в Интернете". Github.com . Получено 2015-03-05 .
  24. ^ "JavaScript-порт ZLib DEFLATE для браузера". Github.com . Получено 2015-03-05 .
  25. ^ "Epic Games выпускает 'Epic Citadel' в Интернете". UnrealEngine.com (пресс-релиз). 2 мая 2013 г. Архивировано из оригинала 30 ноября 2016 г. Получено 24 октября 2014 г.
  26. ^ "Unreal Engine 3, портированный на JavaScript и WebGL, работает в любом современном браузере". ExtremeTech . Ziff Davis . Получено 05.03.2015 .
  27. ^ «О будущем веб-публикаций в Unity». Blogs.unity3d.com. 29 апреля 2014 г.
  28. ^ "HTML5". Clb.demon.fi. Архивировано из оригинала 2015-03-06 . Получено 2015-03-05 .
  29. ^ "Компиляция для Интернета". godotengine.org . 10 ноября 2016 г.
  30. ^ "Emscripten-Generated Code". Kripken.github.io . Получено 2015-03-05 .
  31. ^ "Emscripten-Generated Code". Forandom.github.io . Получено 2015-03-05 .
  32. ^ Гурьянов Александр. «Дюна 2 — Онлайн (браузерная версия)». Эпикпорт . Проверено 05 марта 2015 г.
  33. ^ "Mozilla Banana Bread Demo". Developer.mozilla.org . Получено 2015-03-05 .
  34. ^ "Humble Mozilla Bundle продвигает браузерные игры на базе WebGL". Ars Technica. 15 октября 2014 г. Получено 15 октября 2014 г.
  35. ^ "EM-Dosbox на Github" . Получено 2015-04-09 .
  36. ^ "Перенаправление страницы". Jsmess.textfiles.com . Получено 2015-03-05 .
  37. ^ "HTML5 Fractal Playground". Danielsadventure.info. Архивировано из оригинала 2015-02-22 . Получено 2015-03-05 .
  38. ^ "FAQ". WebAssembly .
  39. ^ "Предложение TC39 по SIMD.js". Ecma TC39. 23 июня 2020 г.
  40. ^ "WebAssembly/binaryen". GitHub . WebAssembly. 25 июня 2020 г. AssemblyScript, который компилирует TypeScript в Binaryen IR; wasm2js, который компилирует WebAssembly в JS
  41. ^ "Binaryen Changelog". GitHub . v97: Удален asm2wasm, который поддерживал бэкэнд fastcomp Emscripten, после удаления fastcomp.(См. также PR#3042.)

Внешние ссылки