如何取消分支预测?

How to cancel branch prediction?

通过阅读 this 我发现了接下来的两个引号:

第一句引述:

A typical case of unpredictable branch behavior is when the comparison result is dependent on data.

第二个引用:

No Branches Means No Mispredicts

对于我的项目,我处理依赖数据并执行许多 ifswitch 语句。我的项目与 Big Data 有关,因此它必须尽可能高效。所以我想根据用户提供的数据对其进行测试,看看分支预测是否真的减慢了我的程序或有帮助。从阅读开始 here:

misprediction delay is between 10 and 20 clock cycles.

最让我震惊的是:

Removing the branches not only improves runtime performance of the code, it also helps the compiler to optimize the code.

为什么要使用分支预测?

有没有办法强制编译器生成没有分支的汇编代码?或者禁用分支预测以便 CPU?这样我就可以比较两个结果了?

现代处理器具有管道,可以让 CPU 比其他方式更快地工作。这是一种并行形式,它在实际需要指令之前的几个时钟周期开始处理指令。有关详细信息,请参阅此处 here

在我们遇到分支之前,这一直很好用。由于我们正在跳跃,因此管道中的工作不再相关。 CPU 然后需要刷新管道并重新启动。这会导致几个时钟周期的延迟,直到流水线再次充满。这称为流水线停顿。

现代 CPUs 在无条件跳转方面足够聪明,可以在填充管道时跟随跳转,从而防止停顿。这在涉及分支时不起作用,因为 CPU 不知道跳转的确切位置。

分支预测试图通过在完全评估跳跃之前猜测 CPU 将遵循哪个分支来解决这个问题。这(当它工作时)防止失速。

由于几乎所有的编程都涉及决策,因此分支是不可避免的。但是当然可以编写分支较少的代码,从而减少由错误预测引起的延迟。一旦我们开始分支,分支预测至少让我们有机会把事情做好,而不是 CPU 流水线停顿。

to see if branch prediction actually slows down my program or helps

分支预测不会减慢程序速度。当人们谈论错过预测的成本时,他们谈论的是与正确预测的分支相比,错误预测的分支要贵多少。

如果不存在分支预测,那么所有分支都会像预测错误的分支一样昂贵。

那么“误预测延迟在 10 到 20 个时钟周期之间”的真正意思是成功的分支预测可以为您节省 10 到 20 个周期。

Removing the branches not only improves runtime performance of the code, it also helps the compiler to optimize the code.

那为什么要使用分支预测?

为什么使用分支预测而不是删除分支?你不应该。如果编译器可以删除分支,它会(假设启用了优化),如果程序员可以删除分支(假设它不损害可读性或者它是一段 performance-critical 代码),他们应该。

虽然这很难使分支预测变得无用。即使你从一个程序中删除了尽可能多的分支,它仍然会包含很多很多分支。因此,由于这一点以及不可预测的分支的成本非常高,分支预测对于良好的性能至关重要。

Is there a way to force the compiler to generate assembly code without branches ?

优化编译器会尽可能地从程序中删除分支(不改变程序的语义),但是,除非我们谈论的是一个非常简单的 int main() {return 0;} 类型的程序,否则这是不可能的删除所有分支。循环需要分支(除非它们是展开的,但只有在您提前知道迭代次数的情况下才有效),大多数 if- 和 switch-statements 也是如此。如果您可以最大限度地减少程序中 ifswitch 和循环的数量,那很好,但是您无法将它们全部删除。

or to disable branch prediction so that CPU? so I can compare both results ?

据我所知,不可能在 x86 或 x86-64 CPU 上禁用分支预测。正如我所说,这永远不会提高性能(尽管它可能使性能可预测,但在使用这些 CPU 的环境中通常不是必需的)。