WebAssembly


WebAssembly

webasembly是一种新型代码,它提供了一种以接近本机的速度在 Web 上运行以多种语言编写的代码的方法,客户端应用程序可以在 Web 上运行,比如可以在浏览器跑C/C++代码

asm.js

2012年,Mozilla 的工程师 Alon Zakai做了一个编译器项目 Emscripten。这个编译器可以将 C / C++ 代码编译成 JS 代码,但不是普通的 JS,而是一种叫做 asm.js 的 JavaScript 变体。

问题

C / C++ 编译成 JS 有两个最大的困难。

  • C / C++ 是静态类型语言,而 JS 是动态类型语言。
  • C / C++ 是手动内存管理,而 JS 依靠垃圾回收机制。

asm.js 就是为了解决这两个问题而设计的:它的变量一律都是静态类型,并且取消垃圾回收机制。除了这两点,它与 JavaScript 并无差异,也就是说,asm.js 是 JavaScript 的一个严格的子集,只能使用后者的一部分语法。

所以可以看到 ts 是 js的超集,asm.js是js的子集

速度快

并且一旦 JS 引擎发现运行的是 asm.js,就知道这是经过优化的代码,可以跳过语法分析这一步,直接转成汇编语言。另外,浏览器还会调用 WebGL 通过 GPU 执行 asm.js,即 asm.js 的执行引擎与普通的 JavaScript 脚本不同。这些都是 asm.js 运行较快的原因。据称,asm.js 在浏览器里的运行速度,大约是原生代码的50%左右。

Emscripten

虽然 asm.js 可以手写,但是它从来就是编译器的目标语言,要通过编译产生。目前,生成 asm.js 的主要工具是 Emscripten

如果要获得asm.js的文件,可以通过学习Emscripten,并用Emscripten便衣你要转换的C/C++文件即可

安装Emscripten

这里

使用

创建一个c文件

#include <stdio.h>
int main(){
    printf("hello world");
    return 0;
} 
emcc hello.c -s WASM=1 -o hello.html

此时可以看到hello.html、hello.css、hello.js文件

emcc hello.c -s WASM=1 -o hello.wasm

此时可以看到hello.wasm文件

编译相关

asm.js为编译目标时,C/C代码被编译为.js文件;以WebAssembly为编译目标时,C/C代码被编译为.wasm文件及对应的.js胶水代码文件。两种编译目标从应用角度来说差别不大——它们使用的内存模型、函数导出规则、JavaScript与C相互调用的方法等都是一致的。我们在实际使用中遇到的主要区别在于模块加载的同步和异步:当编译目标为asm.js时,由于C/C++代码被完全转换成了asm.js(JavaScript子集),因此可以认为模块是同步加载的;而以WebAssembly为编译目标时,由于WebAssembly的实例化方法本身是异步指令,因此模块加载为异步加载。以asm.js为目标的工程切换至WebAssembly时,容易发生Emscritpen运行时未就绪时调用了Module功能的问题,需要按照1.3.3的方法予以规避。

自1.38.1起,Emscripten默认的编译目标切换为WebAssembly。如果仍然需要以asm.js为编译目标,只需要在调用emcc时添加-s WASM=0参数,例如:

> emcc hello.cc -s WASM=0 -o hello_asm.js

WebAssembly是二进制格式,体积小、执行效率高是其先天优势。作为比较,上述命令生成的hello_asm.js约300KB,而WebAssembly版本的hello.jshello.wasm加在一起还不到150KB。在兼容性允许的情况下,应尽量使用WebAssembly作为编译目标。

  • -o:编译后的文件
  • -O1、-O2、-O3、-Oz、-Os、-g 等:编译优化,具体可参考 Emscripten 官网相关章节;(压缩代码)
编译参数

-s WASM=1 (0/1/2)

  • WASM=0生成asm.js格式(适用于WebAssembly不支持的情况)

  • WASM=1生成包含wasm格式

  • WASM=2 asm.js与wasm格式均生成,添加支持判定,优先使用wasm格式。

更多参数看:

csdn文章:Emscripten 编译器(emcc) 命令总结

知乎文章:emscripten 编译参数

野文章(参数在网页下方):从 0 开始快速上手 WebAssembly:Emscripten 使用入门

官网:编译为WebAssembly代码优化

和wasm的对比

如果你对 JS 比较了解,可能知道还有一种叫做 WebAssembly 的技术,也能将 C / C++ 转成 JS 引擎可以运行的代码。那么它与 asm.js 有何区别呢?

回答是,两者的功能基本一致,就是转出来的代码不一样:asm.js 是文本,WebAssembly 是二进制字节码,因此运行速度更快、体积更小。从长远来看,WebAssembly 的前景更光明。

但是,这并不意味着 asm.js 肯定会被淘汰,因为它有两个优点:首先,它是文本,人类可读,比较直观;其次,所有浏览器都支持 asm.js,不会有兼容性问题。

参考

阅读推荐:很棒的 WebAssembly 应用程序的精选列表

asm.js 和 Emscripten 入门教程

C/C++面向WebAssembly编程


文章作者: Hello
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hello !
 上一篇
Docker Docker
Docker概述1. 简要概述IT 软件中所说的 “Docker” ,是指容器化技术,用于支持创建和使用 Linux® 容器。 开源 Docker 社区致力于改进这类技术,并免费提供给所有用户,使之获益。 虚拟机一般来说,比如我们写了一个w
2022-06-05
下一篇 
Chrome插件小指南 Chrome插件小指南
1.开始 重要提示: Chrome 将在所有平台上移除对 Chrome 应用程序的支持。Chrome 浏览器和 Chrome 网上应用店将继续支持扩展。阅读公告并了解有关迁移应用程序的更多信息。 也就是说现在更加推崇插件,而不是chrom
2022-05-28
  目录