2 个版本
新 0.1.1 | 2024年8月13日 |
---|---|
0.1.0 | 2024年8月13日 |
#621 in Rust 模式
每月 190 次下载
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
如您所见,汇编代码解锁了一些其他情况下无法达到的非常低级的优化。