【发布时间】:2015-11-04 08:57:32
【问题描述】:
大多数(如果不是所有)现代处理器都使用一种称为“分支预测”的技术,它可以猜测在 if-then-else 分支中的路径。
我有一个关于该计划的问题。假设我们有这段代码,没有特定的语言:
if(someCondition)
{
// some action
return someValue;
}
// some other action
return someOtherValue;
从逻辑上讲,该代码等价于该代码:
if(someCondition)
{
// some action
return someValue;
}
else
{
// some other action
return someOtherValue;
}
分支预测器将“预测”第二个示例中的分支,但第一个示例呢?它会猜吗?什么将被加载到管道中?忽略块中实际代码的影响,这两个示例是否可以提高速度?
我的猜测,它取决于编译器:如果语句是使用跳转实现的(在汇编中),只有在设置了寄存器中的比较标志时才会执行。现在,汇编指令的具体外观取决于编译器。除非每个编译器都有一种通用的处理方式,我怀疑是否存在,否则这是依赖于编译器的。在这种情况下,最新的 Visual Studio C++ 和 GC++ 编译器会发生什么?
正如 hexafraction 所指出的,返回值之间的关系以及someCondition 的确定方式...分支预测器可能不会起作用。让我们只考虑 true 和 false 作为返回值。对于条件,让我们假设它是一个在函数内部或外部预先确定的字段、一个局部变量和一些算术语句。
老实说,我不怀疑条件是局部变量的情况和字段已在同一函数中预先确定的情况之间有什么区别。
【问题讨论】:
-
请记住,有时编译器可以进行不涉及分支的数值优化。根据您的
someCondition的计算方式以及两个返回值之间的关系,理论上可能在某些情况下可以使用无分支逻辑/位旋转/算术。此外,ARM 等架构具有条件执行,这意味着许多涉及分支的逻辑可以无分支地完成。条件指令携带条件作为操作码的一部分,如果条件不满足,则 inst.变成了 nop。 -
这两段代码不太可能编译成完全相同的机器代码。如果你想谈论 CPU 行为,请比较汇编/机器代码。
-
我认为你可以省略“Logically speak”。这两个 sn-ps 完全相同,我希望编译器为它们输出相同的字节码/程序集。所以分支预测器看不到任何差异,并且会以同样的方式对待它们……
标签: performance optimization compiler-optimization branch-prediction