23 次重大发布
0.30.0 | 2021 年 9 月 17 日 |
---|---|
0.28.0 | 2021 年 6 月 9 日 |
0.25.0 | 2021 年 3 月 16 日 |
0.21.0 | 2020 年 11 月 5 日 |
0.0.0 | 2018 年 12 月 11 日 |
#1622 in WebAssembly
4.5MB
105K SLoC
Lightbeam
Lightbeam 是一个针对 WebAssembly 的优化单遍流式编译器,旨在用于 Wasmtime。
输出质量
已经 - 在具有非常少量的相对简单的优化规则的情况下 - Lightbeam 产生了出人意料的高质量输出,考虑到它的限制。它甚至为某些工作负载产生了比 Cranelift、Firefox 或两者都更好的代码。以下是一个非常简单的例子,这是 Rust 中的递归 Fibonacci 函数
fn fib(n: i32) -> i32 {
if n == 0 || n == 1 {
1
} else {
fib(n - 1) + fib(n - 2)
}
}
在启用优化编译时,rustc 将产生以下 WebAssembly
(module
(func $fib (param $p0 i32) (result i32)
(local $l1 i32)
(set_local $l1
(i32.const 1))
(block $B0
(br_if $B0
(i32.lt_u
(get_local $p0)
(i32.const 2)))
(set_local $l1
(i32.const 1))
(loop $L1
(set_local $l1
(i32.add
(call $fib
(i32.add
(get_local $p0)
(i32.const -1)))
(get_local $l1)))
(br_if $L1
(i32.gt_u
(tee_local $p0
(i32.add
(get_local $p0)
(i32.const -2)))
(i32.const 1)))))
(get_local $l1)))
Firefox 的优化编译器产生以下汇编(标签已清理)
fib:
sub rsp, 0x18
cmp qword ptr [r14 + 0x28], rsp
jae stack_overflow
mov dword ptr [rsp + 0xc], edi
cmp edi, 2
jae .Lelse
mov eax, 1
mov dword ptr [rsp + 8], eax
jmp .Lreturn
.Lelse:
mov dword ptr [rsp + 0xc], edi
mov eax, 1
mov dword ptr [rsp + 8], eax
.Lloop:
mov edi, dword ptr [rsp + 0xc]
add edi, -1
call 0
mov ecx, dword ptr [rsp + 8]
add ecx, eax
mov dword ptr [rsp + 8], ecx
mov ecx, dword ptr [rsp + 0xc]
add ecx, -2
mov dword ptr [rsp + 0xc], ecx
cmp ecx, 1
ja .Lloop
.Lreturn:
mov eax, dword ptr [rsp + 8]
nop
add rsp, 0x18
ret
启用优化后,Cranelift 产生类似的结果
fib:
push rbp
mov rbp, rsp
sub rsp, 0x20
mov qword ptr [rsp + 0x10], rdi
mov dword ptr [rsp + 0x1c], esi
mov eax, 1
mov dword ptr [rsp + 0x18], eax
mov eax, dword ptr [rsp + 0x1c]
cmp eax, 2
jb .Lreturn
movabs rax, 0
mov qword ptr [rsp + 8], rax
.Lloop:
mov eax, dword ptr [rsp + 0x1c]
add eax, -1
mov rcx, qword ptr [rsp + 8]
mov rdx, qword ptr [rsp + 0x10]
mov rdi, rdx
mov esi, eax
call rcx
mov ecx, dword ptr [rsp + 0x18]
add eax, ecx
mov dword ptr [rsp + 0x18], eax
mov eax, dword ptr [rsp + 0x1c]
add eax, -2
mov dword ptr [rsp + 0x1c], eax
mov eax, dword ptr [rsp + 0x1c]
cmp eax, 1
ja .Lloop
.Lreturn:
mov eax, dword ptr [rsp + 0x18]
add rsp, 0x20
pop rbp
ret
而 Lightbeam 产生更小的代码,内存访问次数比两者都少(并且比 Firefox 的输出块数少)
fib:
cmp esi, 2
mov eax, 1
jb .Lreturn
mov eax, 1
.Lloop:
mov rcx, rsi
add ecx, 0xffffffff
push rsi
push rax
push rax
mov rsi, rcx
call fib
add eax, [rsp + 8]
mov rcx, [rsp + 0x10]
add ecx, 0xfffffffe
cmp ecx, 1
mov rsi, rcx
lea rsp, [rsp + 0x18]
ja .Lloop
.Lreturn:
ret
显然,我并不是在提倡用 Lightbeam 代替 Firefox 的优化编译器,因为后者只有在接收到优化后的 WebAssembly 时才能真正产生更好的代码(因此调试模式或手动编写的 WebAssembly 可能会产生更差的输出)。然而,这表明即使在流式编译器的限制下,也可以绝对地产生高质量的汇编输出。对于上面的汇编,Lightbeam 的输出速度比原生速度慢 15%。这对于 Lightbeam 的预期用途至关重要,即实时系统希望有良好的运行时性能,但不能容忍编译器爆炸。
规范合规性
Lightbeam 通过了 100% 的规范测试套件,但这并不意味着它完全符合规范。希望随着我们对它进行模糊测试,我们可以找到任何问题,并将 Lightbeam 带到可以在生产中使用的状态。
参与其中
您可以在 Wasmtime 问题跟踪器 中提交问题。如果您想参与其中,请加入 Bytecode Alliance Zulip,有人会指导您去正确的位置。我希望我能说“您能做的最有用的事情就是尝试使用它,并在发现问题时提交问题”,但直到它通过规范测试套件,这不会很有帮助。
依赖关系
~37MB
~1M SLoC