WebAssembly
WebAssembly(wasm) 是一种运行在现代 web 浏览器中的新型代码,并且提供新的性能特性,同时提升了性能。它设计的目的不是为了手写代码,而是为诸如 C、C++ 和 Rust 等源语言提供一个有效的编译目标(就是类似与JAVA的字节码 .class)。
对于 Web 平台而言,这具有巨大的意义——这为客户端 App 提供了一种在 Web 平台以接近本地速度的方式运行多种语言编写的代码的方式;在这之前,客户端 App 是不可能做到的。(简单说,就是客户端App在不重写代码的前提下,移植为Web端)
而且,你在不知道如何编写 WebAssembly 代码的情况下就可以使用它。WebAssembly 的模块可以被导入的到一个 Web App(或 Node.js)中,并且暴露出供 JavaScript 使用的 WebAssembly 函数。JavaScript 框架不但可以使用 WebAssembly 获得巨大性能优势和新特性,而且还能使得各种功能保持对网络开发者的易用性。
深入解释
先说JavaScript的这门语言本身的缺陷。
JavaScript没有静态变量类型。在项目运行的过程中,引擎会对执行次数较多的function记性优化,引擎将其代码编译成Machine Code后打包送到顶部的Just-In-Time(JIT) Compiler,下次再执行这个function,就会直接执行编译好的Machine Code。但是由于JavaScript的动态变量,上一秒可能是Array,下一秒就变成了Object。那么上一次引擎所做的优化,就失去了作用,此时又要再一次进行优化。
WebAssembly就是为解决这个问题诞生的,(asm.js是前身)WebAssembly提升了JavaScript很大的性能,那WebAssembly和JavaScript是什么关系,是协作关系。
由于WebAssembly的诞生,很多应用都有了Web版本,因为1.是Web性能的提升。2.是其他语言(例如c/c++)也可以编译成wasm,不需要代码重写,就可以移植到Web
WASI接口规范
为了让多种语言编译成WebAssembly,并且运行在各种后端上,(无论前端使用的框架是 jQuery 或 vue 或 react , 无论后端使用 java node.js 或者 java 还是 go)必须对多种语言做接口对接规范,这就是WebAssembly System Interface(wasi)
wasi-sdk
是wasi规范下的wasm编译器,可以把源文件构建为WASM字节码
要安装 WASI SDK,请下载wasi-sdk 版本并将存档解压到默认路径
/opt/wasi-sdk
要将源文件构建为 WASM 字节码,我们可以输入以下命令:
/opt/wasi-sdk/bin/clang -O3-o test.wasm test.c
为什么要在浏览器之外使用WebAssembly?
就像 Javascript 一样,在 WebAssembly 出现后不久,它就不再局限于浏览器。
很多人心中可能有一个疑问:我把C/C++或者Rust程序直接编译成目标机器码就可以了,为什么还要用WebAssembly?这里首先要介绍WebAssembly的沙箱功能。当程序编译成WASM模块,再加载到运行引擎中时,实际上你的模块运行在其私有的沙箱中。沙箱中的程序不能访问沙箱以外的地址空间,否则将被运行引擎终止并返回异常,同时WASM程序调用API来访问系统资源时也会受到运行引擎的监管。这样的沙箱功能可以在许多场景下提供传统的原生编译程序无法支持的功能。
- 安全运行第三方代码:这个功能在云端或者边缘计算中非常有意义,也是现代容器技术如Docker的核心价值之一。在移动设备、物联网设备、智能小家电以及可信运行环境上对这样的功能也有非常强烈的需求。
- 跨平台与环境的应用:考虑到WebAssembly是由W3C定义的标准化字节文件格式,当某些产品需要提供类似浏览器方式来装载第三方模块时,使用WebAssembly作为媒介格式是一个非常有吸引力的方案。假设你有一个很好的图像识别算法,你可以把你的算法以WASM模块的方式发布。其他人通过集成WAMR这样的引擎就可以在不同架构、不同平台、不同环境调用这个算法,比如在云端容器、可信执行环节(TEE)、物联网设备上都可以调用。
- 超轻量级:WASM规范的设计充分考虑了在浏览器上需要通过网络从服务器端下载并即时运行的需求,操作码的设计相当精简。通过开发阶段的编译不再需要对下载程序进行文本解析,实例的对象与内存模型也较为简单。这些特点使WASM模块可以非常快地完成加载进入执行状态,创建一个执行实例只需要很少量的资源。
- 高性能:WebAssembly的字节码设计充分考虑了即时编译的友好性,不仅可以达到很快的编译速度,还可以获得很高的运行速度。
- 动态模块加载:这个功能在小设备上尤其有用,过去固件必须统一编译、统一更新,如今通过固件中的WASM运行引擎,可以动态加载和执行WASM模块。
- 重用海量C/C++库资源: 你也许需要在JS、Java或者Python程序中调用一些C/C++库,传统方式只能使用各种语言自身的绑定接口来集成这些第三方C/C++库。现在我们可以把第三方C/C++库源程序编译成WASM模块,然后通过先绑定WAMR或者其他WASM引擎来执行WASM模块。例如在JVM上通过JNI绑定了WAMR,就不用再使用JNI去绑定其他C/C++库了
字节码联盟
Mozilla、英特尔、RedHat和Fastly公司宣布成立字节码联盟(Bytecode Alliance)
Wasmtime
Wasmtime之前由于Mozilla主导, 现由bytecode alliance接管,Wasmtime是开源的WebAssembly和WASI的小型高效运行时。它在Web外部运行WebAssembly代码,既可以用作命令行实用程序,也可以用作更大应用程序中嵌入的库。
WAMR
WebAssembly Micro Runtime(wamr)最早英特尔公司在GitHub上开源了,现在应该由合作组织字节码联盟进行更新。
也是在浏览器外部运行WebAssembly代码
WAMR项目一开始的设计目标:
- 菜单式编译框架,支持使用者选择不同的模块、功能和特性编译生成最终产品;
- 在资源消耗控制方面,WAMR运行引擎的二进制文件在WASM解释器模式下只有85KB,在AoT模式只有50KB。16KB内存就可以跑起来一个WASM小程序,经过一些微调内存消耗甚至可以低至8KB;
- 在性能方面,WAMR提供了经典(classic)和快速(fast)两个解释器版本,相比常规的Java和JS解释器具有更高的速度。AoT和JIT模式通过LLVM编译框架把WASM生成目标平台的机器指令,能够达到接近GCC编译的速度;
- AoT模块加载器能支持在Linux、SGX和ZephyrOS上加载预编译到机器指令的WASM模块。
WAMR功能与特性一览
WAMR项目包括以下三部分功能:
- iwasmVM内核,是WASM字节码的执行引擎,支持解释器、提前编译 (AoT) 和实时编译 (JIT)多种模式;
- WASM 应用程序API和多实例应用框架;
- WASM 应用程序的动态管理;
- WAMR支持许多非常有价值的特性,便于开发者使用,并且支持更广泛的应
场景。主要特性列举如下:
- 可选择libc支持方案:如果WASM 应用程序需要调用libc的库函数,可以选择基于WASI的标准 libc支持,或者在嵌入式环境中使用内建libc子集支持。开发者可以根据需要选择合适的模式
- 提供易用的C-API用来嵌入WAMR到宿主程序中
- 支持将Native API导出到 WASM 应用程序
- 支持多个WASM模块动态加载与调用
- 提供线程管理和支持WASM应用使用pthread 库
- 多架构的支持,目前WAMR已经支持如下多种架构:X86-64、X86-32、ARM、THUMB、AArch64、MIPS、XTENSA
- 多系统的支持,目前已经支持的系统包括Linux、Zephyr、MacOS、 VxWorks、 AliOS-Things、 Intel Software Guard Extension (Linux)、Android等
WAMR运行模式简介
https://bytecodealliance.github.io/wamr.dev/blog/introduction-to-wamr-running-modes/
版权归原作者 瞎胡跑的嘟嘟¸ 所有, 如有侵权,请联系我们删除。