You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Rust编译时使用x86-64原生128bit by 64bit DIV指令?

如何让Rust编译器在128位除以64位的场景中使用x86-64原生DIV指令?

你需要在Rust中执行由两个u64(hi和lo)拼接成的128位数值除以64位除数的操作,x86-64指令集的DIV指令原生支持该操作,但当前代码却调用了低效的__udivti3(128位除以128位)函数。你已经通过数学推导证明:在hi < divisor的约束下,商必然能放入64位,不会触发DIV指令的溢出异常。以下是两种可行的解决方案:


方法1:使用内联汇编直接调用DIV指令

通过内联汇编手动实现操作,完全控制指令生成,彻底绕开编译器的保守优化逻辑:

pub fn div(hi: u64, lo: u64, divisor: u64) -> u64 {
    assert!(hi < divisor);
    let mut quotient: u64;
    
    unsafe {
        // x86-64 DIV指令规则:rdx:rax作为被除数,除以rdx中的除数,商存入rax,余数存入rdx
        asm!(
            "div rdx",
            inout("rax") lo => quotient,
            inout("rdx") hi => _,
            in("rdx") divisor,
            options(nostack, preserves_flags)
        );
    }
    
    quotient
}

该代码直接生成div rdx指令,完全利用硬件原生支持,性能最优。


方法2:给编译器提供明确约束,引导生成DIV指令

通过不稳定特性和强制内联,给编译器传递更明确的优化信号,促使它生成原生指令(依赖Rust版本和编译优化等级):

#![feature(core_intrinsics)]
use core::intrinsics::unchecked_div;

#[inline(always)]
pub fn div(hi: u64, lo: u64, divisor: u64) -> u64 {
    assert!(hi < divisor);
    let dividend = ((hi as u128) << 64) | (lo as u128);
    
    // 用unchecked_div告知编译器无需处理溢出情况
    unsafe { unchecked_div(dividend, divisor as u128) as u64 }
}

注意:需要启用core_intrinsics不稳定特性,且必须用--release模式编译以开启优化。


验证结果

编译时执行rustc --release --emit asm your_code.rs查看生成的汇编代码,两种方法都能生成原生DIV指令,而非调用__udivti3函数。

内容的提问来源于stack exchange,提问作者ubw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:45:33