正确的分支预测是免费的吗?

Are correct branch predictions free?

假设您编写了一些具有 if 语句和条件的代码,其中 if 语句对于整个 运行 程序始终为真,但在编译时无法获知条件始终为真(可能是在命令行中指定的)

在这种情况下,您希望 cpu 能够预测到这一点并始终选择正确的路径。

这是否意味着有了分支预测,代码就好像根本没有 if 语句一样快?

或者,还有实际成本吗?

我可以想象一些可能不会消失的成本...

那些是真的吗?还有其他的吗?

好吧,让我给出典型的工程答案;这取决于。

不同的处理器进行不同的分支预测。有很多方法可以进行分支预测。其中一些将使您场景中的每个分支都正确,而另一些则不会。

除了我在大学为计算机体系结构编写的一个分支预测实现之外,我不知道任何特定分支预测实现的细节,但我知道分支预测不是一个标准化模块。只要它运行代码,您就可以根据需要实现分支预测器的好坏。

有的方法会占用资源,有的不会。始终选择 true 是一个分支预测器,请记住,这不是一个很好的选择。

分支预测器是处理器中许多令人着迷的部分之一,我鼓励您继续学习更多,并尝试设计您自己的简单处理器!

您将必须执行分支(在首先解决所有依赖关系之后),这将占用执行资源(端口、队列条目等),尽管任何替代方法(例如条件移动)也需要同等的努力至少。即使是预测者最终也必须检查他们是否正确。

此外,大多数无序 CPU 还使用专用队列来跟踪分支,例如参见 Haswell 中的分支顺序缓冲区 - http://www.realworldtech.com/haswell-cpu/3/。如果您有太多分支,这可能会填满并成为限制。一些微架构还可能对更新分支预测器的带宽施加其他限制,最终限制您可以处理这些分支的速率(通过阻止执行或提交)。

关于代码可缓存性 - 是的,您自然会有一些代码用于两个路径,但同样 - 如果分支在程序中具有某些功能性目的,您将不得不拥有这些代码。分支可能会改变代码的组织方式(取决于编译器优化),但这似乎是次要影响。如果整个 if 条件是多余的,那么这同样适用于您的代码中可能存在的任何代码膨胀。

一些架构可以使正确预测的分支或多或少地自由。这叫做分支折叠。基本上发生的事情是,当前端的分支预测器看到它之前遇到的分支并且其目标已知时,它不会将分支沿管道发送,而是可以在分支目标处发送指令。前端还是要看到分支,但是后端永远不会,所以如果后端稍微落后一点,气泡就会平衡,就好像分支从来没有存在过一样。

但这还不是全部。一个分支很可能前几次都没​​有被预测错误,如果是条件分支,不知何故条件还是要解决。