gcc __builtin_expect似乎没有生成正确的代码

时间:2013-03-27 16:25:17

标签: c optimization gcc built-in

以下两个代码段产生完全相同的汇编代码,即使分支包含不同的分支预测。

假设我们有 test0.c

#define likely(x)       __builtin_expect((x), 1)
#define unlikely(x)     __builtin_expect((x), 0)

int bar0();
int bar1();
int bar2();
int bar3();

int foo(int arg0) {
  if (likely(arg0 > 100)) {
    return bar0();
  } else if (likely(arg0 < -100)) {
    return bar1();
  } else if (likely(arg0 > 0)) {
    return bar2();
  } else {
    return bar3();
  }
}

test1.c

#define likely(x)       __builtin_expect((x), 1)
#define unlikely(x)     __builtin_expect((x), 0)

int bar0();
int bar1();
int bar2();
int bar3();

int foo(int arg0) {
  if (unlikely(arg0 > 100)) {
    return bar0();
  } else if (unlikely(arg0 < -100)) {
    return bar1();
  } else if (unlikely(arg0 > 0)) {
    return bar2();
  } else {
    return bar3();
  }
}

正如您通过比较两个片段所看到的,这两个片段对每个分支都有不同的分支预测(可能()与不太可能())。

然而,当它从linux盒子编译时(ubuntu 12.04 32bit,gcc 4.6.3)。这两个来源几乎产生相同的输出。

$gcc  -c -S -o test0.s test0.c
$gcc  -c -S -o test1.s test1.c
$ diff test0.s test1.s
1c1
<   .file   "test0.c"
---
>   .file   "test1.c"

如果有人能够解释这一点,那将是一个很大的帮助。 感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

您发布的两个文件是相同的 - 我认为这不是您真正做过的。

使用-O2或更高版本进行编译,您需要启用优化功能。然后应该生成不同的代码。

答案 1 :(得分:0)

我在ARM7(Allwinner sun71 A20)和gcc 6.3(-O3)上进行了一些测量,尽管从其他测试中可以明显看出,采用分支的成本更高,但#like和#unlike之间没有性能差异。比不采用它,即使在完美的分支预测的情况下。

相关问题