wasm系列之初探胶水代码
发布时间:2025-05-23 20:14:26 发布人:远客网络
一、wasm系列之初探胶水代码
1、深入探讨胶水代码,专注于WebAssembly(WASM)与原生JavaScript/C函数间的交互。
2、在之前的小节中,我们构建了一个基础的Hello World示例,其中包含了用于WASM与JS互转的胶水代码的hello.js文件。现在,让我们聚焦于这个JavaScript文件中的关键代码。
3、首次调用的入口点就是createWasm,这是一个关键角色。
4、紧接着,实例化WASM模块的首选方法是使用WebAssembly.instantiateStreaming()。如果失败,将通过WebAssembly.instantiate()作为备选方案。
5、成功实例化后的返回值,将通过receiveInstance()方法处理。
6、需要注意的是,WASM加载、编译、实例化过程的异步特性。由于此性质,如果我们试图提前使用Module方法,可能会遇到错误。这是因为WASM的runtime还未准备就绪。
7、解决这个问题的办法是注册一个回调。一旦runtime就绪,该回调将执行所需的操作,确保流程的顺利进行。
8、深入学习WASM系列的后续内容可在GitHub同步更新。如果有兴趣持续关注更新,不妨考虑star这个项目。
二、什么是webassembly(wasm)
1、WebAssembly(Wasm)是一种基于栈式虚拟机的二进制指令集,设计为编程语言的编译目标,旨在为Web客户端和服务器应用提供部署。最初定义时,我对其概念感到困惑,通过研究资料逐渐形成了对Wasm的理解。Wasm由“Web”和“Assembly”两部分组成,其中“Web”表明其与前端密切相关,“Assembly”意味着它是汇编指令集,与机器码和CPU指令集相关联。
2、Wasm指令集是为虚拟机设计的,而非直接在硬件上运行。它具有通用性,能够被多种编程语言编译为Wasm字节码,并在Web环境中执行。指令集的实现包括操作码、操作数以及特定功能,最终转化为0,1序列供CPU执行。
3、WebAssembly的诞生背景与JavaScript的动态类型特性有关。JavaScript的动态类型导致解释器在执行代码时进行类型判断,影响执行速度。为解决这一问题,V8引擎采用了即时编译(JIT)技术,监控并编译常用代码为CPU可直接执行的机器码。尽管如此,JavaScript的动态类型特性仍可能引发性能问题,尤其是在项目规模和复杂度增加时。
4、在WebAssembly的发展历程中,Google引入了Native Client(NaCl)技术,允许C语言编写的程序在浏览器中运行。然而,由于开发难度和兼容性问题,该技术最终未得到广泛普及。随后,PNaCl技术被提出,但同样面临挑战。最终,在2017年,Google转向WebAssembly,以实现跨平台兼容性和性能优化。
5、ASM.js是Mozilla在2013年推出的,作为JavaScript的严格子集,它允许将C/C++代码编译为目标语言,从而使用AOT(预编译)策略在运行前将代码编译为机器码,提高运行速度。通过编译器将C/C++代码转换为ASM.js,然后Web引擎在运行时进行优化。
6、WebAssembly于2015年4月开始发展,并在2019年12月成为万维网联盟(W3C)的推荐标准。目前,浏览器对Wasm的支持程度相对较高,已经较为普遍。
7、体验Wasm内部结构,首先编写C++程序(如斐波那契数列),通过Emscripten工具将C++代码编译为Wasm模块。生成的字节码文件包含多个Section,如Function Section和Code Section,这些Section包含特定的数字对应指令操作符。Wasm字节码可以使用WAT(WebAssembly Text Format)格式进行解读,通过安装WABT工具并执行wasm2wat命令,可以将字节码转换为可读的文本格式。
8、加载、编译、实例化和调用是使用Wasm模块的基本步骤。加载时读取Wasm字节码到本地,通常通过fetch API从网络获取。编译在Worker线程中进行,将Wasm代码转换为平台相关代码。实例化时,将宿主环境对象导入到Wasm模块中,如操作DOM的方法。调用时,通过实例化对象调用Wasm模块中的方法。
9、WebAssembly提供了两种类型的API:js API和Web API。js API(如WebAssembly.instantiate)用于完成编译和实例化过程,而Web API支持流式编译实例化,通过WebAssembly.instantiateStreaming实现。
10、尝试使用WebAssembly,可以构造一个包含add方法的Wasm模块,通过WebAssembly.instantiate进行编译和实例化。对应的C++代码和字节码文件会生成,然后在控制台执行相关代码,输出结果验证编译效果。
11、WebAPI尝试包括流式编译,使用fibonacci.wasm模块进行性能测试。通过简单的HTTP服务返回Wasm文件,使用html文件展示斐波那契数字计算,并与原生JavaScript版本进行比较,结果显示使用Wasm的计算速度明显提升。
12、WebAssembly在前端应用中已成功落地,如eBay引入WebAssembly优化条形码扫描功能,提高识别率;AutoCAD将C++代码移植到Web平台,提升性能;Google地球采用WebAssembly重写,实现跨平台运行。
13、WebAssembly不仅局限于Web环境,还可以应用于Out-of-web环境中,通过WASI(WebAssembly System Interface)标准,实现与操作系统交互,适用于嵌入式、IOT物联网、云、AI和区块链等场景。有了WASI标准,应用架构的跨平台兼容性得到极大提升,可以使用任意编程语言编译为Wasm,并在不同平台部署。
14、总结,WebAssembly作为一种通用的编译目标,能够提高前端性能,兼容多种编程语言,简化跨平台开发。对于遇到性能瓶颈的前端项目,考虑使用WebAssembly可以带来显著的性能提升。
三、1.Js引擎与Wasm
1、Js引擎与Wasm的关系及各自特点如下:
2、Js引擎:定义:JavaScript引擎是负责解析和执行JavaScript代码的软件组件。工作原理:通过词法分析、语法分析和语义分析将JavaScript代码转换为可执行的机器码。具体过程包括识别关键字、构建抽象语法树、判断运行时错误并优化代码。局限性:在处理高密度数学计算或复杂计算任务时,JavaScript引擎的效率相对较低,因为其设计初衷是为了提供灵活的编程语言和丰富的Web功能,而非高性能计算。
3、Wasm:定义:WebAssembly是一种为Web设计的二进制指令格式,旨在提供接近原生代码的执行速度。引入目的:为了弥补JavaScript在处理复杂计算任务时的性能不足,WebAssembly提供了一种更高效的代码执行方式。工作原理:WebAssembly代码通常以.wasm文件形式存在,这些文件可以通过JavaScript引擎加载并执行。WebAssembly代码在编译时已被优化为高效的二进制格式,因此可以在运行时提供更快的执行速度。优势:WebAssembly提供了比JavaScript更高的性能,特别是对于需要大量计算的任务。此外,它还支持多种编程语言编译为WebAssembly格式,从而增加了跨平台兼容性和代码复用性。
4、总结: Js引擎是负责解析和执行JavaScript代码的核心组件,但在处理高性能计算任务时存在局限性。 Wasm作为一种高效的二进制指令格式,旨在提供接近原生代码的执行速度,以弥补JavaScript在性能方面的不足。通过结合使用Js引擎和Wasm,开发者可以在保持Web应用灵活性和丰富功能的同时,实现高性能计算任务。