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 个 Crates 中使用 (2 直接)

Apache-2.0 WITH LLVM-exception

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