如何避免大部分未采用的条件分支?

How to avoid mostly untaken conditional branches?

提问人:KGM 提问时间:7/10/2020 最后编辑:KGM 更新时间:7/10/2020 访问量:178

问:

请考虑以下情况:

  • 你有一个宏在整个代码中经常做一些事情。(例如,一些异常处理)

  • 这个宏通常很少做,但会定期出现某些情况,使得宏必须做更多......

  • 这可以很容易地实现,使用条件分支来选择是需要复杂代码还是简单代码,如果需要复杂代码,则使用分支......但这可能会导致以下严重的性能问题:

    • 许多现代分支预测器对多个分支使用相同的预测结构,因此从其他分支收集的数据会影响每个分支的预测!因此,大多数时间未采用的压倒性分支计数可能会“混淆”分支预测器,从而对其他分支做出可怕的预测!

我怎样才能解决这个问题?

请注意,因为复杂的代码很少被调用,所以在这种情况下我真的不在乎效率!

(研究的起点可能是:像 java 这样的语言如何解决这个问题?

性能 IF-语句 程序集 优化 分支预测

评论

2赞 fuz 7/10/2020
几乎从未被采取的分支通常被分支预测器很好地识别出来。我认为你对这种情况太担心了。
0赞 KGM 7/10/2020
我不知道。。。我的恐惧是基于 Agree Predictors 在 agner.org/optimize/microarchitecture.pdf 中的工作方式。我认为如果你用从未执行过的分支淹没它,它将变得完全无用......我担心有很多预测器在工作......
0赞 KGM 7/10/2020
也就是说,它会完美地识别这些分支,但完全搞砸了其余的分支。
0赞 fuz 7/10/2020
这通常不会发生。分支预测器有足够的条目,很难将其与普通代码混淆。此外,除非相关代码很热,否则偶尔的错误预测不太可能真正产生影响。
2赞 Peter Cordes 7/10/2020
@fuz:污染/稀释全球历史听起来像是现代IT-TAGE预测器(Haswell,Zen(?))的一个合理问题,其中预测的索引基于最后分支的历史(如15到20?但我认为 OP 应该尝试用从未采用过的条件分支与普通分支来对一些现实情况进行基准测试,作为失败的最佳情况基线。(或者只是一个填充指令长度的指令,没有 ,以保持前端对齐与 cmp/near-jcc 相同。它可能没有那么糟糕。nnopcmpjcc

答: 暂无答案