Emscripten效率问题
一,Asm.js介绍
Asm.js是Mozilla的一个研究项目,它做为JavaScript的子集,在支持Asm.js的浏览器中,可以被快速的解释并运行(作为JS的汇编语言来设计的),但在不支持或者不完全支持的浏览器中运行的效率会有一部分差异。
地址:http://asmjs.org/
二,Emscripten和Asm.js
Emscripten实际上就是将C/C++代码编译为Asm.js,在Firefox和Chrome中,从Firefox 22开始完全支持Asm.js,而Chrome来说,从Chrome 28到现在Chrome 56都是部分支持。
三,由Asm.js引起的一个效率问题
C/C++中申请的内存在堆上申请,堆的大小由物理内存控制,而在Asm.js中是使用ArrayBuffer模拟堆,既然是ArrayBuffer,那么默认的情况下,需要设置初始的大小,在Emscripten编译选项中“
TOTAL_MEMORY"
是用来设置默认ArrayBuffer的大小。
"TOTAL_MEMORY"的大小需要根据应用程序的需要设置,因为在应用程序运行前,会预先申请这么大的内存。如果"TOTAL_MEMORY"是1024*1024*1024,
通过"任务管理器"我们会发现,浏览器打开我们的应用后,还未进行任何操作就会占用1G多的内存,这样会导致过多的使用内存资源。
编译选项"
ALLOW_MEMORY_GROWTH"可以解决这个问题,如果"
ALLOW_MEMORY_GROWTH=1",此时对应Asm.js的堆的大小是可增长的,如果现有的大小不足,可以重新改变HEAP的大小,以满足程序运行过程中不断扩充的内存使用。
在”
ALLOW_MEMORY_GROWTH=1|0“两种情况下,一部分用户发现了一个严重影响效率的问题,在某些C/C++程序中,如果使用”
ALLOW_MEMORY_GROWTH=1“编译生成的js程序,其运行效率会比”
ALLOW_MEMORY_GROWTH=0“慢2倍以上,查找其中原因发现,是在Chrome中Asm.js的动态扩充内存操作影响,目前暂时无法有效的解决此种问题。
四,效率问题的其他解决方案
经过查找,发现了其他解决方案,
1.WebAssembly,此种解决方案中由于WebAssembly是一套新的标准,而Emscripten是支持生成此种标准的编译生成,但WebAssembly标准目前还在制定中,没有被发布,所以主流浏览器中只处于是实验性阶段。
2.Chrome PNacl,对于Chrome浏览器来说,PNacl是一个可以让C/C++程序做为Native Code运行在Chrome上,从而大大提升运行效率,而PNacl通信方式是采用异步通信方案,完全可以与Emscripten的JS兼容。