#low-level #macro #asm #register #optimization #sbpf

sbpf-asm-macros

为低级 sBPF ASM 功能提供人体工程学宏

2 个版本

0.1.1 2024年8月13日
0.1.0 2024年8月13日

#621 in Rust 模式

Download history · Rust 包仓库 190/week @ 2024-08-11 · Rust 包仓库

每月 190 次下载

MIT 许可证

7KB

sbpf-asm-macros

一系列宏,用于启用最佳低级 sBPF 功能,例如直接设置寄存器值,这些值在其他情况下是无法访问的。

用法

这些宏使您能够直接设置寄存器,并可能在将来提供其他低级功能,以实现极端优化到字节码级别。以下是一个示例。

接近最优的字节码

一个简单的示例,接近最优的 Rust 程序,它检查代币账户的余额与指令数据中的金额是否匹配,如下所示:

#[no_mangle]
pub unsafe extern "C" fn entrypoint(ptr: *mut u8) -> u64 {
    let ix_balance = (ptr as *const u8).add(0x2918) as *const u64;
    let account_balance = (ptr as *const u8).add(0x00a0) as *const u64;
    if *ix_balance > *account_balance {
        return 1
    }
    0
}

这会产生以下汇编代码

ldxdw r2, [r1+160]    ; 1CU
ldxdw r1, [r1+10520]  ; 1CU
mov64 r0, 1           ; 1CU
jgt r1, r2, +1        ; 1CU
mov64 r0, 0           ; 1CU
exit                  ; 1CU

CU 成本: 成功:6 CU 失败:5 CU

最优的字节码

由于 SVM 初始化其返回寄存器 0 为 0,因此可以通过删除入口点的返回签名并预期返回寄存器的值为 0 而不是显式设置它来节省计算单元。使用 sbpf-asm-macros,我们能够以人体工程学的方式访问返回寄存器以进行此类优化

#![cfg_attr(target_os = "solana", feature(asm_experimental_arch, asm_const))]
use sbpf_asm_macros::set_return_imm;

#[no_mangle]
pub unsafe extern "C" fn entrypoint(ptr: *mut u8) {
    let ix_balance = (ptr as *const u8).add(0x2918) as *const u64;
    let account_balance = (ptr as *const u8).add(0x00a0) as *const u64;
    if *ix_balance > *account_balance {
        set_return_imm!(1);
    }
}

这会产生以下汇编代码

ldxdw r2, [r1+10520] ; 1CU
ldxdw r1, [r1+160]   ; 1CU
jge r1, r2, +2       ; 1CU
lddw r0, 1           ; 1CU
exit                 ; 1CU

CU 成本: 成功:4 CU 失败:5 CU

如您所见,汇编代码解锁了一些其他情况下无法达到的非常低级的优化。

没有运行时依赖项