我刚看到这篇文章: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
中的最小分支而不会降低性能?Math.min(...)
函数就是那个三元语句...... 答案 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可以在一个周期内完成。