如何阻止Rust编译器重排代码以保障性能测量准确性?
阻止Rust编译器指令重排的方法
编译器会对无数据依赖的代码进行重排优化,导致你的性能测量失效,以下是两种可靠的解决办法:
方法一:使用std::hint::black_box
black_box会向编译器提示,包裹的操作具有未知的副作用或数据依赖,编译器无法对其进行重排优化。把expensive_function()的调用用它包裹即可:
std::hint::black_box(expensive_function()); let t1 = Instant::now(); let ptr = get_mut_ptr::<AtomicUsize>(); (ptr).store(some_value, Ordering::Relaxed); let t2 = Instant::now();
方法二:插入内存屏障
通过std::sync::atomic::fence插入内存屏障,强制编译器和CPU执行完屏障前的所有操作后,再执行屏障后的代码。在expensive_function()之后、Instant::now()之前插入最强顺序的屏障(SeqCst)即可:
expensive_function(); std::sync::atomic::fence(std::sync::atomic::Ordering::SeqCst); let t1 = Instant::now(); let ptr = get_mut_ptr::<AtomicUsize>(); (ptr).store(some_value, Ordering::Relaxed); let t2 = Instant::now();
补充说明
如果expensive_function()本身是可内联的函数,还可以给它加上#[inline(never)]属性,但这仅能阻止内联优化,对指令重排的抑制效果不如前两种方法,通常不推荐单独使用。
内容的提问来源于stack exchange,提问作者Samuel Hapak
相关产品推荐
相关产品推荐

