Rust中__builtin_ia32_addcarryx_u64(带进位加法)的等价实现是什么
__builtin_ia32_addcarryx_u64 功能说明与Rust高性能实现方案 功能说明
__builtin_ia32_addcarryx_u64 是x86架构下C/C++编译器针对ADX扩展指令集提供的内置函数,输入1位进位标识、两个64位无符号整数,输出相加后的64位结果,返回值为相加后产生的新1位进位(类型为u8,取值仅0或1)。
Rust高性能实现方案
Rust下有两种经过性能验证的实现方式,优化后性能和C/C++内置函数完全一致:
1. 标准库便携实现(推荐)
Rust 1.70及以上稳定版本为所有整数类型提供了原生的带进位加法方法carrying_add,编译器在开启对应CPU指令集优化时会自动生成最优机器码:
/// 完全对齐__builtin_ia32_addcarryx_u64的功能签名 /// 输入:carry_in 输入进位,a/b 两个64位加数,out 存储加法结果的可变引用 /// 返回:加法产生的新进位(0/1的u8) pub fn addcarryx_u64(carry_in: u8, a: u64, b: u64, out: &mut u64) -> u8 { let (result, new_carry) = a.carrying_add(b, carry_in != 0); *out = result; new_carry as u8 }
- 该实现兼容所有CPU架构,不需要额外unsafe标注
- 编译时添加ADX指令集支持(RUSTFLAGS="-C target-feature=+adx")后,编译器会自动将其优化为单条
adcx指令,无额外开销
2. 显式汇编实现(极致性能场景)
如果需要完全控制指令生成,避免不同编译器版本的优化差异,可以使用x86_64平台专用的汇编实现:
#[cfg(target_arch = "x86_64")] #[target_feature(enable = "adx")] pub unsafe fn addcarryx_u64_asm(carry_in: u8, a: u64, b: u64, out: &mut u64) -> u8 { let result: u64; let carry_out: u64; core::arch::asm!( "adcx {result}, {a}", a = in(reg) a, result = inout(reg) b => result, inout("rflags") carry_in as u64 => carry_out, options(pure, nomem, nostack), ); *out = result; (carry_out & 1) as u8 }
- 该实现为unsafe方法,调用前需要确保运行程序的CPU支持ADX指令集
- 生成的机器码和C/C++内置函数完全一致,性能无任何损失
内容的提问来源于stack exchange,提问作者Rafaelo
相关产品推荐
相关产品推荐

