#wasm-interpreter #stitch #实验性 #平台 #优化 #兄弟 #全局

bin+lib makepad-stitch

使用 Rust 编写的实验性 Wasm 解释器,旨在非常快速且轻量级

1 个不稳定版本

0.1.0 2024 年 5 月 13 日

WebAssembly 中排名第 242

MIT 许可证

690KB
13K SLoC

Stitch

Stitch 是一个使用 Rust 编写的实验性 Wasm 解释器,旨在非常快速和轻量级。

注意

如果您计划在项目中使用 Stitch,您应该仔细考虑以下内容

Stitch 通过依赖兄弟调用优化(兄弟调用是一种限制尾调用的形式,其中被调用者与调用者具有相同的签名)来实现其速度。Rust 不提供保证尾调用被优化的机制,但在实践中,LLVM 会自动在满足某些约束的 64 位平台上优化兄弟调用。

请注意,LLVM 也不严格保证优化兄弟调用,因此理论上,此功能可能会退化,这会导致 Stitch 停止工作。实际上,我认为这种情况不太可能发生,因为这种退化会对现有代码的性能产生重大负面影响。然而,这种可能性不能完全排除。

我们可以为 Stitch 添加一个回退模式,该模式依赖于跳板而不是尾调用。这将允许 Stitch 在面对 LLVM 退化的情况下继续工作,但也会消除其大部分速度优势,并且无论如何,这种回退模式尚未实现。

性能

Stitch 非常快。我已经将它与其他几个引擎进行了比较,以下表显示了这些引擎

名称 描述
Wasmi 我所知的唯一一个使用 Rust 编写的 Wasm 解释器。
Wasm3 我所知的最快的 C 语言编写的 Wasm 解释器。
Wasmtime Wasm 的 JIT 编译器。

Coremark 结果

以下表格显示了 Stitch 和我比较的其他引擎在三个主要 64 位平台上的 Coremark 分数

引擎 Mac Linux Windows
Stitch 2950 1684 4592
Wasm3 2911 1734 3951
Wasmi 788 645 1574
Wasmtime 12807 13724 34796

以下表格显示了每个平台使用的 CPU

平台 CPU
Mac Apple M2 Pro @ 3.5GHz
Linux Intel Xeon E312xx @ 2.1GHz
Windows Intel i9-13900K @ 3.0GHz

如您所见,Stitch 在所有主要平台上都比 Wasmi 快几倍。与 Wasm3 相比,它在 Mac 上略快,在 Linux 上略慢,在 Windows 上则显著更快。

Stitch 比 Wasmtime 慢得多(Mac 上大约慢 4 倍,Linux 和 Windows 上大约慢 8 倍),这是预期的,因为 Wasmtime 是 JIT 编译器,而 Stitch 是解释器。

Stitch比Wasmi快的原因在于Stitch使用线程代码,而Wasmi使用解释器循环。

Stitch在Mac上略快于Wasm3,但在Linux上略慢,这可能是由于与Wasm3相比,Stitch每条指令有更多变体,这给指令缓存带来了压力。我怀疑这使Stitch在拥有大指令缓存的Apple M2 Pro上具有优势,而Wasm3在拥有较小指令缓存的Intel Xeon E312xx上具有优势。

Stitch在Windows上显著快于Wasm3的原因可能是Stitch使用System V调用约定为其线程代码,而Wasm3使用vectorcall调用约定,后者在传递整数参数时可用的寄存器较少。

以上结果是通过进入coremark目录并运行获得的

cargo run --release

这将运行coremark-minimal.wasm测试套件,并打印上述每个引擎的结果。

微基准测试

为了更好地了解Stitch的速度,我还将其与几个微基准测试进行了比较。以下表格显示了在Mac上(使用Apple M2 Pro @ 3.5GHz)每个基准测试的结果

名称 时间
fac_iter 1_048_576 2.8561 ms
fac_rec 32 276.82 ns
fib_iter 1_048_576 5.0592 ms
fib_rec 32 52.136 ms
fill 0 1_048_576 3.9256 ms
sum 0 1_048_576 4.4489 ms

以上结果是通过运行获得的

cargo bench

编译时间

Stitch非常轻量级。它没有0个非开发依赖项,由大约15,000行代码组成。

以下表格显示了Stitch在Mac上相对于其他用Rust编写的Wasm引擎的编译速度(使用Apple M2 Pro @ 3.5GHz)

引擎 编译时间
Stitch 2.29秒
Wasmi 15.61秒
Wasmtime 81.02秒

如你所见,Stitch的编译速度比Wasmi或Wasmtime都要快得多。如果你认为编译时间很重要,Stitch可能是一个不错的选择。

特性

Stitch支持以下完成的Wasm提议

提议 状态
可变全局变量的导入/导出
非捕获浮点数到整数的转换
符号扩展运算符
多值
JavaScript BigInt到WebAssembly i64集成
引用类型
批量内存操作
固定宽度SIMD
WASI

可移植性

Stitch在所有三个主要64位平台(Mac、Linux和Windows)上编译并通过了Wasm核心测试套件。

Stitch目前不支持32位平台。原因是我还没有找到在32位平台上使LLVM执行兄弟调用优化(欢迎提供想法)的方法。

如果你需要比这更广泛的可移植性,Wasmi或Wasm3可能更适合你。

安全性

Stitch有一个安全的API,但在底层使用了大量不安全代码。这些不安全代码尚未经过任何形式的审计,因此我无法提供任何强有力的安全保证。如果你需要强有力的安全保证,Wasmi可能更适合你。

尽管如此,我已经做出了严肃的努力,确保Stitch中的所有不安全代码都是可靠的,并符合堆栈借用模型。不幸的是,由于Miri是一个解释器,因此无法在Miri上运行Stitch,因为Miri不优化兄弟调用。

用法

作为CLI应用程序

安装CLI

cargo install makepad-stitch

运行Wasm二进制文件

makepad-stitch <file_name> <func_name> [<arg>]*

作为Rust库

要了解如何将Stitch用作Rust库,请参阅Stitch crate文档。

设计

待办事项

无运行时依赖项