GMTC – Web Assembly 专题

GMTC有一场讲Web Assembly(以下简称WA),虽然没有颠覆之前的认知,但多少可以拾人牙慧拿来用用。

认识WA

WebAssembly是一种新的编码方式,可以在现代的网络浏览器中运行。它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如C/C ++等语言提供一个编译目标,以便它们可以在Web上运行。它也被设计为可以与JavaScript共存,允许两者一起工作。(摘自MDN)

如果对WA的概念还是很陌生,那么最浅显易懂的说法是:
在浏览器运行(C/C++等)语言编写的语言。
这样的操作仿佛开启了新纪元,其实我们联想以下,浏览器为JavaScript提供了执行环境,那为什么不能为其他语言提供呢?以前的Flash(AS脚本运行在AVM中)似乎早已开创了先河。

所以WA的出现,目前来看是对浏览器的一种增强,但与Flash、Silverlight等插件本质的不同,下面会讲WA的本质。

解读WA

WA是什么

WA是一套语言(指一类低级语言),这被写入W3C的规范中,而不是指某个浏览器提供的扩展功能。

(图片出处:WebAssembly Code Explorer)
上图左边的16进制表示的代码就是WA所表达的内容。哦?看不懂?当然,这段代码对应的二进制(Binary)是给机器读的。
上图右边的文本是WA的Text Format,即一种语义化表达,其中包含了WA的各项指令的应用。也就是说,WA是包含特殊指令的一种语言,学习过汇编的同学立刻就感觉到了亲切。

WA涵盖的内容

作为一类语言,WA自然有语法,有其语言特性。这里不多做扩展,举几个例子。
1. 数据类型
就四类,整形、浮点,支持32/64bit。
i32: 32-bit integer
i64: 64-bit integer
f32: 32-bit floating point
f64: 64-bit floating point

  1. 指令
    每种数据类型都有各自的运算指令。
    举个栗子,i32.const 1 i32.const 2 i32.add,实现一个加法过程。

  2. 模块
    表示一个已经被浏览器编译为可执行机器码的WebAssembly二进制代码。一个模块是无状态的并且像一个二进制大对象(Blob)一样能够被缓存到IndexedDB中或者在windows和workers之间进行共享(通过postMessage()函数)。一个模块能够像一个ES2015的模块一样声明导入和导出。

  3. 线性内存(Linear Memory)
    一个可变大小的ArrayBuffer。它包含了一个连续的字节数组并且WebAssembly的低级内存存取指令可对其进行读写操作


  4. 一个可变大小的包含引用类型(比如,函数)的带类型数组。它包含了不能作为原始字节存储在内存中的引用(为了安全和可移植性的原因)

  5. 实例
    一个模块及其在运行时使用的所有状态,包括内存、表格和一系列导入值。一个实例就像一个已经被加载到一个拥有一组特定导入的特定的全局变量的ES2015模块。

WA的加载运行

浏览器为WA的运行提供了环境,并且提供了API让WA与JS进行交互。这一切都源于WebAssembly API
目前有很多手段引入WA模块,如通过Fetch或者XHR API与WebAssembly JavaScript API结合在一起来获取、编译和实例化.wasm文件。
这里提到了.wasm文件,也就是我上面提到的WA语言编译后的文件。
举一个样例:
1. 假设有一份C源码,hello.c

#include <stdio.h>

int factorial(int n) {
  if (n == 0)
    return 1;
  else
    return n * factorial(n-1);
}
  1. 需要利用一个编译工具 Emscripten
    通过编译工具的命令将hello.c 转换成.wasm
    emcc hello.c -s WASM=1 -o hello.html
    对应的.wasm,可能是如下的样子:

此时,便于理解,可以将wasm转换成可识别的WA文本格式,如下:

(module
  (func $i (import "imports" "imported_func") (param i32))
  (func (export "exported_func")
get_local 0
i64.const 0
i64.eq
if i64
    i64.const 1
else
    get_local 0
    get_local 0
    i64.const 1
    i64.sub
    call 0
    i64.mul
end
  )
)

应用

本次大会中提到了WA的应用案例,宣讲方讲了他们的两个实战产品用例:
1. 视频过程中基于被摄人物脸部位置识别:
大概的方案描述:截取视频帧 -> WA处理 -> 获取面部坐标传给JS -> JS 利用 canvas 在视频的上方渲染一个对应人脸位置的框,并提醒用户将脸放在框里。
2. 表情识别、动态贴纸,这些也都是基于人脸位置,做到了实时的位置交互。

以上demo在演示过程中,帧率都达到了50fps,还是相当给力的。

最后说一下WA的野心。
WA不仅仅在浏览器中可以使用,更可以在浏览器外使用。所以扣一下题,WA绝对不是一个浏览器的特殊能力,而是对跨平台计算能力的崭新探索。

参考

https://webassembly.org/docs/use-cases/

发表评论

电子邮件地址不会被公开。 必填项已用*标注