asm.js Emscripten WebAssembly

参考
Emscripten与拼音输入法的相遇
VS2010 c/c++ 本地化 emscripten 配置
大家对Emscripten这个项目有什么想法
Web3D Porting - Emscripten VS FlasCC
HTML5标准与性能之四:asm.js
【探索】在 JavaScript 中使用 C 程序
asm.js:面向未来的开发
asm.js
Emscripten

一、asm.js Emscripten

在提到 Emscripten 之前,我们先来回顾一下 JavaScript 的发展历史。
JavaScript 的历史
JavaScript在1995年问世的时候,目的是在浏览器中打造一种轻量的脚本语言,用来辅助页面的呈现以及与使用者互动。为了这个目的,JavaScript被设计的非常灵活,让开发者在撰写过程中不会被太多的规则所限制。虽然在保持灵活性的同时可能会牺牲效率,但如果JavaScript只是被用来提高网页的互动性的话,似乎也不会有什么大问题。
但是科技的趋势总是难以预料的,应用程序的领域渐渐从操作系统转移到了网络环境中,Web应用变成了热门关键字,JavaScript的效率这时成了最大的瓶颈。终于在2008年左右,各家浏览器开始放出支持JIT(Just-In-Time)编译的JavaScript引擎,让浏览器可以在它判断需要时将部分的JavaScript代码即时编译成源代码来执行,性能因此得到提升。
JIT引擎虽然解决了当时的瓶颈,但JavaScript的性能还是没办法和真正的源代码相提并论,主要的限制就在于JavaScript的灵活性让它不容易被优化。举例来说,JavaScript选择采用与大部分的脚本语言相通的动态类型机制(dynamic typing),在编辑时没有办法确定变量的形态,因此JIT引擎就必须为之后在执行时可能进行的各种变量形态转换提前做准备,浪费了很多资源。
asm.js 与 Emscripten
为了解决此类问题,David Herman、Luke Wagner 和 Alon Zakai 等人提出了一种JavaScript 的子集,命名为asm.js。这个子集的目的是让开发者避开JavaScript中无法最佳化的部分,例如:不直接使用JavaScript的对象,改为通过长矩阵来模糊记忆体的管理,避免使用引擎的garbage collection等等。由于asm.js单纯是JavaScript的子集,并没有加入任何新的语法,所以写出来的代码在所有的浏览器上都是可以被解析和执行的,只是当浏览器真正支持asm.js的规范时,其JIT引擎就能采用更有效率的最佳方式来进行编译,进而获得更好的执行效率。

asm.js Emscripten WebAssembly_第1张图片
图一、Emscripten 编译出來的程序代码片段

图一使用Emscripten编译出来的JavaScript程序代码片段,你应该可以想象如果要用人脑写出如何asm.js规范的程序代码,似乎不是那么容易(这就是为什么它会以组合语言asm命名)。事实上, Mozilla并不打算让人直接撰写asm.js,他们开发了一个叫做Emscripten的编译器,让开发展可以直接把C/C++的源代码“编译”成JavaScript的程序代码,听起来是不是轻松多了!

asm.js是由Mozilla提出的一个基于JS的语法标准,主要是为了解决JS引擎的执行效率问题,尤其是使用Emscripten从C/C++语言编译成JS的程序的效率,目前只有Mozilla的Firefox Nightly中支持。

Emscripten是一个基于LLVM的项目,可以把C和C++代码编译成高度优化的JavaScript代码(asm.js格式),可以在web中以近乎原生的速度运行C和C++代码,而且不需要插件。

Emscripten是Mozilla的一个实验性项目,目的是把C/C++开发的应用编译成JS或HTML5的应用,编译过程中需要首先把C/C++程序编译成LLVM的中间代码,然后再转换成JS代码,这样做的主要原因是可以很好地复用现有的针对LLVM的优化。

asm.js的目标比typescript、dart、pnacl都要大的多,它有可能成为web未来的基础设施。简单说,它可能成为web上的jvm或.net,你可以把asm.js的代码看成未来web平台的bytecode。未来jvm及.net平台的语言也可以编译到asm.js,而不仅仅是c、c++,这实际意味着:未来所有的语言都应该可以编译为asm.js,从而使web摆脱js(或加上dart等极少数几种语言)的限制。ECMAScript6/7、dart再好,也不可能满足所有人的需求。

二、Emscripten与FlasCC

Emscripten的主要流程为:

C/C++ -> LLVM -> Emscripten -> JavaScript/HTML

其编译环境配置相对来说较为简单,可以见这里有比较详细的介绍。本人参考在VS里边配置了一下但是没有成功,不过不使用VS的话倒也没什么影响,简单写一个bat也可以完成编译的流程。
FlasCC的主要流程为:

C/C++ -> GCC -> LLVM -> FlasCC -> .abc -> SWF

FlasCC的编译环境相对来说就比较高了,其它的如Java,Python等都不说了,除此外主要就是需要Cygwin的环境(这空间很可观,跟NDK环境配置有得一拼);还有一点就是FlasCC的64位环境要求,否则32位下的内存搞不定,囧。。。
整体来说FlasCC要求的编译环境比Emscripten要高不少。

三、Emscripten测试

1.需要先安装一下notepad++编辑器的C语言环境,参考MinGW的安装以及如何配置C,notepad++搭建C语言环境(Dev c++)
2.安装好Emscripten
参考emscripten getting start
3.测试
写一个hello.c。然后CMD进入相应路径后,运行命令emcc hello.c -o hello.html

#include

int main() {
  printf("hello, world! by cuixu\n");
  return 0;
}
四、WebAssembly字节码技术

如何评论浏览器最新的 WebAssembly 字节码技术?

作者:余建荣
链接:https://www.zhihu.com/question/31415286/answer/51902492
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

一个常见的asm.js应用形式就是Emscripten,在这个项目里,C++代码将会被Clang编译为LLVM bitcode,然后LLVM bitcode再被Fastcomp (emscripten的编译后端) 编译为插入了特殊标记的JS(也就是asm.js),这样的JS在普通JS引擎能运行,但在对Asm.js优化的引擎里可以得到巨大的性能提升。但这样的解决方案有一个问题:编译出来的JS文件非常巨大,这样会严重增加加载时间。回到上面的应用形式,我们发现既然这样的JS是LLVM bitcode再编译的,那直接传输LLVM bitcode不就行了吗?当然以LLVM bitcode为标准是不可取的(一个是未必足够优化,一个是web标准可不能和某个特定的解决方案挂钩),所以就有了所谓的WebAssembly了……所以WebAssembly是这样一个解决方案:1. 二进制,可以完全编译到对应的asm.js2. 一个用于不支持WebAssembly的JS引擎的polyfill,也就是要做一个JS版的WebAssembly到asm.js的编译器所以可以看出来:1. WebAssembly的运行性能和asm.js没有任何区别2. 主要优点是在减少传输体积和提高parse性能上

作者:罗志宇链接:https://www.zhihu.com/question/31415286/answer/58022648来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
既然 JIT 遇到的问题是类型不确定问题和有一些语言功能,比如异常,for in , JIT 起来很麻烦, 我可不可以搞个方法让用户不去用这些功能,同时让他们把用的类型都标注出来啊。
按照这个思路, 催生了两种实现路径:
一种是 Typescript, Dart, JSX 为代表的,基本思想是, 我搞个其他的语言,这个语言是强类型的,所以程序猿们需要指定类型,然后我把它编译成 Javacript 不就行了嘛。强类型的语言编译成弱类型还不容易,什么,不知道怎么编? 把类型去掉就行了嘛。
另一种是火狐的 Asm.js 为代表的, 做一个 javascript 子集, 同时试图利用标注的方法,加上变量类型, 如果觉得好难理解,这就是个典型的例子:

Paste_Image.png

加上一堆没有什么卵用提示 x 其实是个 int, 然后有一个能够识别这些符号的JS引擎,你就可以不用猜类型了哦, 事实上,由于有了类型,连传统的 AOT 都成为了可能(Ahead of time, 不懂的话,想象一下,就是和 C/C++ 那种编译方式就好了)。如果你没有注意到,第二种的速度提升潜力比第一种要大非常多。因为第一种,无论如何,也是就是让JIT (即时编译) 快一点, 第二种那可直接就编译了啊 (AOT).

Web Assembly 就是第二种方式,说到底,Mozilla, Google,Microsoft,Applel 觉得 Asm.js 这个方法有前途,想标准化一下,大家都能用。
有了大佬们的支持,Web Assembly 比 asm.js 要激进很多。 Web Assembly 连标注 Js 这种事情都懒得做了,不是要 AOT 吗? 我直接给字节码好不好?(后来改成 AST 树)。对于不支持 Web Assembly 的浏览器, 会有一段 Javascript 把 Web Assembly 重新翻译为 Javascript 运行, 这个技术叫 polyfill, HTML5 刚出来的时候很常用的一个技术。

https://zhuanlan.zhihu.com/p/25800318
https://zhuanlan.zhihu.com/p/25669120

你可能感兴趣的:(asm.js Emscripten WebAssembly)