代码优化以避免分支

时间:2014-10-01 00:34:18

标签: java performance minimum branch-prediction

我刚看到这篇文章:Compute the minimum or maximum of two integers without branching

首先是" [o] n一些稀有机器,其中分支价格昂贵......"

我曾经认为分支总是很昂贵,因为它经常迫使处理器清除并重新启动其执行管道(例如,见Why is it faster to process a sorted array than an unsorted array?)。

这给我留下了几个问题:

  • 文章的作者是否错了?或者这篇文章可能是在分支出现问题之前编写的(我无法在其上找到日期)。
  • 现代处理器是否有办法完成(x < y) ? x : y中的最小分支而不会降低性能?
  • 或者所有现代编译器是否只是自动执行此hack?具体来说,Java做什么?特别是因为它的Math.min(...)函数就是那个三元语句......

1 个答案:

答案 0 :(得分:6)

  

文章的作者是否错了?或者这篇文章可能是在分支出现问题之前编写的(我无法在其上找到日期)。

最老的评论是5岁,所以没有热门新闻。然而,不可预测的分支总是很昂贵,5年前也是如此。与此同时,它变得更糟,因为现代CPU可以在每个周期执行更多操作,因此错误预测的分支会花费更多的工作。

但从某种意义上说,作家是对的。我们的PC和服务器中没有大多数CPU,但在情况不同的嵌入式设备中找不到。

  

现代处理器是否有办法完成像(x

是和否。 AFAIK Math.max始终被翻译为条件移动,这意味着没有分支。您拥有max可能会也可能不会使用它,具体取决于JVM收集的统计信息。

没有银弹。通过可预测的结果,分支更快。确切地说,CPU识别出什么样的模式很难。 JVM只是查看分支获取的频率,并使用大约18%的魔术阈值。有关详细信息,请参阅我自己的question and answer

  

或者所有现代编译器是否只是自动实现此hack?具体来说,Java做什么?特别是因为它的Math.min(...)函数只是那个三元语句......

它实际上是编译器内在的。每当JITc看到这个方法被调用时,它就会特别处理它。复制方法时,它没有特殊处理。

在这种情况下,内在函数不是很有用,因为无论如何它都会被大量优化。对于像Long#numberOfLeadingZeros这样的方法,内在函数是必不可少的,因为code相当长而且很慢,现代CPU可以在一个周期内完成。