我想在 Rust 中使用区间算术,为此我需要向上或向下设置舍入模式。据我从一些搜索中了解到,设置舍入模式会影响性能,所以我想在编译时设置它。
不可靠,不。问题是 LLVM 后端不提供任何修改舍入模式的支持,尽管最近已经有一些建议来解决这个问题,但在不久的将来不太可能得到解决。
您也许可以在程序开始时调用 C
fesetround
函数(在 fenv.h
中),但问题是某些优化(例如常量折叠)已经使用默认舍入执行模式。
如今,您可以使用(不稳定的)持续评估功能来防止这种情况发生。需要注意的是,您需要一致地调用辅助函数,并提供两种实现,其中之一应该是常量可评估的。该函数看起来有点像
pub fn add_rounding_up(a: f64, b: f64) -> f64 {
#[cfg(target_arch = "x86_64", target_feature="avx")]
fn runtime_impl(a: f64, b: f64) -> bool {
let mut c = 0.0f64;
asm! {
<vldmxcsr, vaddsd, etc.>,
in(a),
in(b),
out(c),
}
c
}
// ... possibly more implementations for other arches ...
const fn const_impl(a: f64, b: f64) -> f64 {
add_f64_ru_fallback(a, b) // needs to be in terms of constant f64 expressions
}
unsafe { const_eval_select((a, b), const_impl, runtime_impl) }
}
我有一些舍入运算的废弃实现(加法、减法、乘法、除法、融合乘加、平方根),这些实现应该是常量可评估的here,以及针对 NEON、SSE、AVX 和 AVX512 的专门运行时实现,尽管我只测试了 NEON 和 AVX 实现——而且不是很好。