Asm.js
asm.js是一个intermediate programming language,设计目的是使采用C语言等编程语言编写的计算机软件能运行为web applications,同时性能特征明显优于标准JavaScript。
asm.js包括一个JavaScript的严格子集,其中的代码采用具有手动内存管理(例如C语言)的静态类型语言编写,代码使用一个源代码至源代码编译器(例如基于LLVM的Emscripten)翻译。通过将语言特性限制在适合提前优化和其他性能改进的范围内,性能得到了提高。
Mozilla Firefox是第一个实现针对asm.js优化的浏览器,从Firefox 22开始使用。[1]
设计
asm.js由JavaScript语言的一个严格子集组成。它可以显著提高采用具有手动内存管理(例如C)的静态类型语言编写的web applications在使用源代码至源代码编译器转换为JavaScript后的性能。Asm.js的目标并不是提高手写JavaScript代码的性能,也不实现增强性能以外的其他目的。
通过将语言特性限制在适合提前优化和其他性能改进的范围内,其旨在具有比标准JavaScript更接近于本地(原生)代码的性能特征。[2]通过使用JavaScript的一个子集,asm.js很大程度上支持所有主要的web browsers[3],这不同于WebAssembly或Google Native Client等途径。
代码生成
asm.js通常不直接编写,而是作为一种通过编译器生成的中间语言,该编译器获取C++或其他语言的源代码,然后输出asm.js。
例如,提供下列C语言代码:
int f(int i) {
return i + 1;
}
Emscripten将输出下列JavaScript代码:
function f(i) {
i = i|0;
return (i + 1)|0;
}
注意新增的|0
和去除的类型说明符。在JavaScript中,按位运算符会将操作数转换为32位有符号整数并给出整数结果。这意味着使用0的bitwise OR为一个无作用的操作,只是将值转换为整数。通过对每个参数这样做,确保了从外部代码调用该函数时,该值被转换为正确的类型。这也用于返回值,在该情况下确保添加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) {
curr = (curr + 1)|0;
}
return (curr - ptr)|0;
}
在生成的代码中,变量MEM8实际上是一个类型缓冲区的逐字节“视图”,它充当asm.js代码的堆(heap)。
性能
因为asm.js在浏览器中运行,所以性能很大程度上取决于浏览器和硬件。编译为asm.js的C程序的初步基准通常比使用Clang的本地编译慢一倍以上。[4]
这种超过普通JavaScript的性能增益主要是由于100%的类型一致性以及几乎没有垃圾回收(内存是手动管理的大型类型数组)。这个更简单的模型没有动态行为,没有内存分配或释放,只有一组简单、定义明确的整数和浮点操作,从而可实现更好的性能和优化潜力。[來源請求]
Mozilla在2013年12月的基准测试显示:“使用float32优化的Firefox可以运行所有基准,只比原生速度慢不到1.5倍。[5] Mozilla指出本地编译代码的性能不是单个度量,而是一个范围,使用不同的本地编译器(此例中为Clang与GCC)将提供不同性能的代码。“事实上,在一些基准测试比如Box2D、FASTA和copy中,asm.js与Clang比较接近,或者比Clang到GCC还接近Clang。在一种情况下,asm.js甚至在Box2D上略微击败Clang。”
实现
Emscripten项目提供了可以编译C和C++(或其他任何可转换为LLVM IR的语言)代码为asm.js的工具。[6]
所有支持JavaScript较新版本的浏览器都应该能支持运行asm.js代码,因为它是该规范的子集。
部分浏览器的实现针对asm.js进行了特别优化:
- Mozilla Firefox是第一个实现针对asm.js优化的网页浏览器,自Firefox 22开始使用。 OdinMonkey是Mozilla在Firefox中使用的asm.js提前编译器,它是IonMonkey(SpiderMonkey的JIT编译器)的一个组件。
- 微软在Microsoft Edge使用的JavaScript引擎Chakra中实现了asm.js支持,执行验证以产生高度优化的JIT代码。[7]
- Google Chrome的V8 JavaScript引擎在Chrome 28中对asm.js基准测试的性能是以前Chrome版本的两倍以上,[8]尽管Chrome的V8没有使用提前编译。
采用
目前几乎所有基于asm.js的应用程序都是使用Emscripten或Mandreel编译为asm.js的C/C++应用程序。
到目前为止,已有不少programming languages、application frameworks、programs、libraries、games、game engines及其他软件已被ported。[9]部分名单见下:
编程语言
- C/C++: Clang和LLVM
- Lua VM: Lua virtual machine[10]
- Perl: port of (micro)perl-5.16.3[11]
- Python – port of CPython[12]
- Ruby – port of Ruby[13]
应用程序框架
- pepper.js: Ports of miscellaneous PNaCl apps (earth, voronoi, bullet, etc.)[14]
- Qt: ports of various Qt demos, plus KDE apps, such as Kate[15]
程序和库
- OpenGL, SDL, and SDL2[16]
- Vim (Vi IMproved)[17]
- FreeType: TrueType font rendering in JavaScript, using FreeType[18]
- SQLite[19]
- GNU Privacy Guard[20]
- ctags[21]
- gnuplot[22]
- Graphviz[23]
- zlib[24]
游戏引擎
- Unreal Engine 3: was ported in 4 days[25][26]
- Unreal Engine 4
- Unity[27]
- ScummVM,它支持许多经典的冒险游戏[28]
- Godot[29]
游戏
- Doom: the open source Freedoom game assets running on PrBoom, which is based on the open source Doom code[30]
- SuperTux[31]
- Dune II via OpenDune[32]
- BananaBread based on Cube 2[33]
- Every game in the Humble Mozilla Bundle[34] (Super Hexagon, AaAaAA! for the Awesome, Osmos, Zen Bound 2, Dustforce DX, Voxatron, FTL: Advanced Edition and Democracy 3)
仿真器
- EM-DOSBox: an Emscripten port of DOSBox[35]
- Start9.io: a web emulation platform targeting multiple gaming architectures
- JSMESS: a port of the MESS emulator for many game consoles and computer systems[36]
数学计算
- HTML5 Fractal Playground[37] – 绘制迭代函数生成的分形,例如Mandelbrot fractal。
参见
- WebAssembly – 一个开发中的用于浏览器的字节码,旨在比asm.js更快地解析
RPython - CrossBridge
- Google Native Client(NaCl)
参考资料
- ^ Firefox 22.0 release notes. Mozilla. [July 4, 2013].
- ^ Asm.js. Asm.js. [2015-03-05].
- ^ asm.js — frequently asked questions. Asmjs.org. July 26, 2014.
- ^ asm.js. Asm.js. [2015-03-05].
- ^ Alon Zakai; Robert Nyman. Gap between asm.js and native performance gets even narrower with float32 optimizations. 20 December 2013 [11 April 2014].
- ^ kripken/emscripten · GitHub. Github.com. [2015-03-05].
- ^ Bringing Asm.js to Chakra and Microsoft Edge. Microsoft. May 7, 2015 [May 7, 2015].
- ^ Chrome 28 Beta: A more immersive web, everywhere. Google. [2013-07-06].
- ^ Home — Demos — Games and Game Engines.
- ^ Lua REPL. Kripken.github.io. [2015-03-05].
- ^ plu. Themucker.github.io. [2015-03-05].
- ^ repl.it — Python. Repl.it. [2015-03-05].
- ^ repl.it — Ruby. Repl.it. [2015-03-05].
- ^ pepper.js Examples. Trypepperjs.appspot.com. [2015-03-05].
- ^ emscripten-qt — Demos. Vps.etotheipiplusone.com. [2015-03-05].
- ^ About Emscripten.
- ^ Vim.js — JavaScript port of Vim. Coolwanglu.github.io. [2015-03-05].
- ^ TrueType Fonts in JavaScript. (原始内容存档于2012-10-12).
- ^ Port of SQLite to Javascript. Github.com. [2015-03-05].
- ^ GnuPG.js. Manuuels.github.io. [2015-03-05].
- ^ ctags in the browser. Github.com. [2015-03-05].
- ^ Gnuplot online. Gnuplot.respawned.com. [2015-03-05].
- ^ A hack to put GraphViz on the web.. Github.com. [2015-03-05].
- ^ JavaScript port of ZLib DEFLATE for the browser. Github.com. [2015-03-05].
- ^ Epic Games Releases ‘Epic Citadel’ on the Web. UnrealEngine.com (新闻稿). May 2, 2013.
- ^ Unreal Engine 3 ported to JavaScript and WebGL, works in any modern browser. ExtremeTech. Ziff Davis. [2015-03-05].
- ^ On the future of Web publishing in Unity. Blogs.unity3d.com. April 29, 2014.
- ^ HTML5. Clb.demon.fi. [2015-03-05].
- ^ Compiling for the Web. godotengine.org. November 10, 2016.
- ^ Emscripten-Generated Code. Kripken.github.io. [2015-03-05].
- ^ Emscripten-Generated Code. Forandom.github.io. [2015-03-05].
- ^ Guryanov Aleksander. Dune 2 - Online (browser version). Epicport. [2015-03-05].
- ^ Mozilla Banana Bread Demo. Developer.mozilla.org. [2015-03-05].
- ^ Humble Mozilla Bundle pushes WebGL-powered browser gaming. Ars Technica. 15 Oct 2014 [15 Oct 2014].
- ^ EM-Dosbox on Github. [2015-04-09].
- ^ Page Redirection. Jsmess.textfiles.com. [2015-03-05].
- ^ HTML5 Fractal Playground. Danielsadvernture.info. [2015-03-05].