移除一个if,Rust过滤快4倍
Branchless Rust: Making a Filter 4x Faster by Removing an If

在Rust开发中,我通常认为代码正确性比性能更重要。但最近在处理一个热点路径时,我发现一个看似简单的过滤操作在数据随机分布时性能极差。通过基准测试,我惊讶地发现保留50%数据的情况比保留99%数据慢了2.6倍。罪魁祸首是CPU的分支预测器:当数据无规律时,预测器频繁猜错导致流水线清空。通过采用无分支编程技巧,将控制依赖转化为数据依赖,我成功消除了不可预测的分支,使最坏情况下的性能提升了近4倍。当然,这种优化是以牺牲最佳情况和代码可读性为代价的,仅建议在性能剖析确认瓶颈时使用。
分支本身很便宜,但预测错误的分支代价高昂。
HN 评论区
110- anematode
这篇文章是 100% AI 生成的。数据挺有意思,但评论部分过于冗长,很难从中提炼出有用的见解。
- Retro_Dev
对无分支方法为何能带来如此显著的速度提升,解释得很棒。我从未真正处理过这个级别的性能优化。一般来说,最好不要太深入干预,让 CPU 这个黑盒自行其是就好。
我倒是好奇,无分支与有分支的性能特征在不同 CPU 或架构上是否一致?如果有一枚 CPU 不试图用分支预测来搞花样,常规算法会不会反而更快?
- amiga386
我一直用 Janet 语言以(有时)隐式(变量)、无分支的方式刷 LeetCode:
(def find-shared-gcd
(comp
(fn [e] (max ;(map (fn [d] (* d ;(map |(- 1 (min 1 (mod $ d))) e)))
(range 1 (+ 1 (min ;e))))))
|((juxt* max min) ;$)))
(defn max-diff `where elements increase` [& numbs]
(reduce max
-1 (filter |(< 0 $) # strip 0s and add -1 in case (= true (apply > numbs))
(map - numbs (accumulate2 min numbs)))))