当前位置: 首页 > 知识库问答 >
问题:

编译器是否具有某些优化启发式方法来支持分支预测?如果没有,为什么不呢?

邢飞白
2023-03-14

这个问题主要是在阅读了Aater Suleman关于从软件方面改进分支预测的文章后的后续问题。作者提供了一种“展开”条件语句的方法,例如在2位饱和计数器方案的情况下增加预测分支的概率。这里有一个努力:

我举个例子解释一下。让我们假设X是0到99之间的随机变量。我想运行下面的代码:

如果(X

但是,如果我将代码编写为:

如果(X

分支预测器更有可能更准确地预测这两个分支,这可能会导致更好的性能,因为分配给这两个分枝的计数器更有可能在执行时保持饱和(因为两个未执行的计数器不太可能)。

一般来说,任何时候当你在if语句中对条件进行and/or运算时,你都应该考虑这个组合是偏向性更大还是偏向性更小,然后选择偏向性更大的版本。

我的问题是:编译器是否一直遵循这种启发式方法?编译器是否有权做这样的事情,因为编译器存在于ISA的范围内,架构和分支预测方案存在于处理器和更具体的硬件实现的范围内?

我的直觉是,以这种方式扩展控制语句不会影响性能,但同时我还没有找到任何证据表明编译器进行了这种优化。如果是这样,为什么他们不呢?我的推理中遗漏了什么?有人能提供一个例子,说明这种优化对于某个架构或预测方案是有害的吗?

谢谢。

共有2个答案

卫志泽
2023-03-14

您可以通过用以下代码替换这段代码来避免这两个分支

if (((unsigned int) X) - 6 < 88)
    do_something ();

__builtin_expect显然无法更改条件是true还是false。它主要用于执行分支比未执行分支慢的处理器。因此编译器将编译

if (__builtin_expect (condition, 0))
    statement;

morestuff ();

对此:

if (condition) goto elsewhere;
backhere: morestuff ();

....

elsewhere: statement; goto backhere;

因此,通常没有分支被占用,而不是通常的分支

if (! condition) goto nextstatement;
statement;
nextstatement: morestuff ();

但在问题中,事情不是这样运作的。如果(电点 1

缪征
2023-03-14

苏勒曼似乎没有意识到

if (X > 5 && X < 95)
  do_something();

if(X > 5)
  if(X < 95)
    do_something();

在 C 和 C 中在语义上是等价的。最新的 C 标准状态 (6.5.13/4):

与按位二进制不同

编译器可能会也可能不会为这两个代码示例生成相同的代码。重写程序以使用一种或另一种形式来提高性能不是一个好主意。结果将在很大程度上取决于编译器版本、ISA,以及可能更多的变量。将这种类型的优化留给编译器,但为编译器提供所需的信息。

一些编译器(如GCC和LLVM)允许您给出如下显式提示:

if (__builtin_expect(X > 5, 1)) {
  // This block is likely to be taken.
}
if (__builtin_expect(X <= 5, 0)) {
  // This block is unlikely to be taken.
}

另一种方法是使用轮廓引导优化。第一步需要运行一个或多个程序测试,以生成包含分支指令统计信息的数据库。在第二步中,编译器可以使用此数据库优化程序。有关详细信息,请参阅编译器手册。

 类似资料:
  • 我的代码经常调用具有多个(不可预测的)分支的函数。当我分析时,我发现这是一个小瓶颈,大部分CPU时间用于条件JMP。 考虑以下两个函数,其中原始函数有多个显式分支。 这是一个新函数,我试图在其中删除导致瓶颈的分支。 然而,当我分析新代码时,性能只提高了大约20%,而且调用本身(对mem_funcs数组中的一个func)花费了很长时间。 第二个变量仅仅是一个更隐含的条件吗,因为CPU仍然无法预测将要

  • 我会给你一点背景。对于大多数操作,我很高兴,测试看起来相当稳定,有4s的隐式等待。 然而,有些时候我知道如果元素要显示在页面上,它已经存在了,所以如果例如我正在对元素列表进行操作,我希望驱动程序不要等待4s来决定每个元素它不在那里,继续前进。 所以当我可以设置驱动程序时。管理()。超时()。隐式wait(100,TimeUnit.millizes)并快速遍历列表,我想在解析完列表后将隐式wait设

  • 我正在使用一个页面对象模型来实现我的自动化,我正在测试类中创建一个页面对象,如下所示。(只是一个示例代码) 但是随着我的页面数量的增加,在测试类中创建页面对象的数量也会增加。我想知道是否有任何其他优化方法来创建页面对象或任何我正在做的是好的?

  • 本文向大家介绍是否有浏览器还支持HTML5的checkValidity()方法?,包括了是否有浏览器还支持HTML5的checkValidity()方法?的使用技巧和注意事项,需要的朋友参考一下 是的,在Google Chrome和Opera中也可以使用。这也很好- 示例

  • 本文向大家介绍举例说明判断浏览器是否支持某个事件的方法有哪些?相关面试题,主要包含被问及举例说明判断浏览器是否支持某个事件的方法有哪些?时的应答技巧和注意事项,需要的朋友参考一下 1.使用 in 运算符,检测对象中是否存在事件