【发布时间】:2012-12-29 06:18:53
【问题描述】:
在最新的英特尔软件开发手册中,它描述了两个操作码前缀:
Group 2 > Branch Hints
0x2E: Branch Not Taken
0x3E: Branch Taken
这些允许对跳转指令进行显式分支预测(操作码如Jxx)
我记得几年前读到,在 x86 上,显式分支预测本质上是 gccs 分支预测内在函数上下文中的无操作。
我现在不清楚这些 x86 分支提示是否是一项新功能,或者它们在实践中是否本质上是无操作的。
谁能解决这个问题?
(即:gccs 分支预测函数是否会生成这些 x86 分支提示?-当前的 Intel CPU 不会忽略它们吗?-这是什么时候发生的?)
更新:
我创建了一个快速测试程序:
int main(int argc, char** argv)
{
if (__builtin_expect(argc,0))
return 1;
if (__builtin_expect(argc == 2, 1))
return 2;
return 3;
}
反汇编成以下内容:
00000000004004cc <main>:
4004cc: 55 push %rbp
4004cd: 48 89 e5 mov %rsp,%rbp
4004d0: 89 7d fc mov %edi,-0x4(%rbp)
4004d3: 48 89 75 f0 mov %rsi,-0x10(%rbp)
4004d7: 8b 45 fc mov -0x4(%rbp),%eax
4004da: 48 98 cltq
4004dc: 48 85 c0 test %rax,%rax
4004df: 74 07 je 4004e8 <main+0x1c>
4004e1: b8 01 00 00 00 mov $0x1,%eax
4004e6: eb 1b jmp 400503 <main+0x37>
4004e8: 83 7d fc 02 cmpl $0x2,-0x4(%rbp)
4004ec: 0f 94 c0 sete %al
4004ef: 0f b6 c0 movzbl %al,%eax
4004f2: 48 85 c0 test %rax,%rax
4004f5: 74 07 je 4004fe <main+0x32>
4004f7: b8 02 00 00 00 mov $0x2,%eax
4004fc: eb 05 jmp 400503 <main+0x37>
4004fe: b8 03 00 00 00 mov $0x3,%eax
400503: 5d pop %rbp
400504: c3 retq
400505: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
40050c: 00 00 00
40050f: 90 nop
我没有看到 2E 或 3E ?也许 gcc 出于某种原因忽略了它们?
【问题讨论】:
-
gcc 没有选项让它吐出程序集吗?你能不能用这些内在函数写一个简短的程序,看看它是否产生了这些? (我知道这不能回答问题的另一半)
-
@Damien_The_Unbeliever:作为更新添加。
-
通常,
__builtin_expect结构只会影响 GCC 优化器。 (效果非常微妙。)您是否尝试过指定-march或-mcpu标志让 GCC 知道您的 CPU 支持这些前缀? -
@duskwuff:尝试使用
-march=corei7并给出相同的输出 -
好的,在这种情况下,我怀疑 GCC 根本不会生成
2E/3E前缀。
标签: gcc x86 x86-64 branch-prediction