为了了解它的性能,我手工编写了一个非常短的asm.js模块,它使用32位整数数学和类型化数组(Int32Array)模拟2D波动方程。我有三个版本,都尽可能相似:
我在http://jsfiddle.net/jtiscione/xj0x0qk3/上留下了一个演示,它允许您在模块之间切换以查看使用每个模块的效果。这三种方法都能工作,但速度不同。这是热点(带有asm.js注释):
for (i = 0; ~~i < ~~h; i = (1 + i)|0) {
for (j = 0; ~~j < ~~w; j = (1 + j)|0) {
if (~~i == 0) {
index = (1 + index) | 0;
continue;
}
if (~~(i + 1) == ~~h) {
index = (1 + index) | 0;
continue;
}
if (~~j == 0) {
index = (1 + index) | 0;
continue;
}
if (~~(j + 1) == ~~w) {
index = (1 + index) | 0;
continue;
}
uCen = signedHeap [((u0_offset + index) << 2) >> 2] | 0;
uNorth = signedHeap[((u0_offset + index - w) << 2) >> 2] | 0;
uSouth = signedHeap[((u0_offset + index + w) << 2) >> 2] | 0;
uWest = signedHeap [((u0_offset + index - 1) << 2) >> 2] | 0;
uEast = signedHeap [((u0_offset + index + 1) << 2) >> 2] | 0;
uxx = (((uWest + uEast) >> 1) - uCen) | 0;
uyy = (((uNorth + uSouth) >> 1) - uCen) | 0;
vel = signedHeap[((vel_offset + index) << 2) >> 2] | 0;
vel = vel + (uxx >> 1) | 0;
vel = applyCap(vel) | 0;
vel = vel + (uyy >> 1) | 0;
vel = applyCap(vel) | 0;
force = signedHeap[((force_offset + index) << 2) >> 2] | 0;
signedHeap[((u1_offset + index) << 2) >> 2] = applyCap(((applyCap((uCen + vel) | 0) | 0) + force) | 0) | 0;
force = force - (force >> forceDampingBitShift) | 0;
signedHeap[((force_offset + index) << 2) >> 2] = force;
vel = vel - (vel >> velocityDampingBitShift) | 0;
signedHeap[((vel_offset + index) << 2) >> 2] = vel;
index = (index + 1)|0;
}
}“普通JavaScript”版本的结构如下所示,但没有asm.js所需的按位运算符(例如“x\0”、“~x”、"arr(x<<2)>>2“等)。
以下是我的计算机上所有三个模块的结果,分别使用Firefox (Developer Edition v. 41)和Chrome (version 44),每次迭代以毫秒为单位:
所以普通的JavaScript在这两种浏览器中都占了上风。如果存在asm.js所需的注释,在这两种注释中性能都会下降3倍。此外,“使用asm”指令的存在有着明显的效果--它对Firefox有一点帮助,并使Chrome屈膝!
奇怪的是,仅仅添加按位运算符就会带来三倍的性能下降,这是通过告诉浏览器使用asm.js无法克服的。另外,为什么告诉浏览器使用asm.js只会在火狐中起到一点作用,而在Chrome中却完全适得其反呢?
发布于 2015-08-05 14:11:12
实际上,asm.js并不是手工编写代码的结果,而是其他语言编译的结果。据我所知,没有任何工具可以验证asm.js代码。您是否尝试过用code编写代码并使用Emscripten来生成asm.js代码?我强烈怀疑,结果将是完全不同的,并对asm.js进行了优化。
我认为混合类型化和非类型化只会增加复杂性,没有任何好处。相反," asm.js“代码更复杂:我试图解析asm.js和jointjs.com/demos/javascript-ast上的普通函数,结果如下:
我想说的是,如果在每个循环中有更多的指令要执行,那么很容易就会慢一些。
发布于 2015-08-09 15:29:07
切换asm.js上下文需要一些修复成本。理想情况下,您只需执行一次,并以asm.js的形式在应用程序中运行所有代码。然后,您可以使用类型化数组控制内存管理,并避免大量垃圾回收。我建议重写分析器并在asm.js中测量asm.js -而不需要上下文切换。
https://stackoverflow.com/questions/31767070
复制相似问题