另一个需要介绍的Builtin函式为 __builtin_expect,这函式的功能主要在提供编译器Branch Prediction的能力,如以下的程式码
void FuncA(int X)
{
if(__builtin_expect(X,1))
{
printf("FuncA 1:%ld\n",X*0x100);
}
else
{
printf("FuncA 2:%ld\n",X);
}
}
void FuncB(int X)
{
if(__builtin_expect(X,0))
{
printf("FuncB 1:%ld\n",X*0x100);
}
else
{
printf("FuncB 2:%ld\n",X);
}
}
int main()
{
FuncA(7);
FuncB(8);
return;
}
执行结果为
FuncA 1:700h
FuncB 1:800h
以gcc 4.1.2搭配-O2进行编译(在这验证环境下,使用-O0,函式__builtin_expect会没有效果),执行结果一致,透过反组译程式码结果如下
FuncA/B (-O0) |
FuncA (-O2) - if(__builtin_expect(X,1)) |
FuncB(-O2)-if(__builtin_expect(X,0)) |
push %ebp mov %esp,%ebp sub $0x8,%esp mov 0x8(%ebp),%eax test %eax,%eax je 80483a9 <FuncA+0x25> mov 0x8(%ebp),%eax shl $0x8,%eax mov %eax,0x4(%esp) movl $0x8048500,(%esp) call 8048298 <printf@plt> jmp 80483bc <FuncA+0x38> 80483a9: mov 0x8(%ebp),%eax mov %eax,0x4(%esp) movl $0x804850d,(%esp) call 8048298 <printf@plt> leave ret |
push %ebp mov %esp,%ebp sub $0x8,%esp mov 0x8(%ebp),%eax test %eax,%eax je 80483f2 <FuncA+0x22> shl $0x8,%eax mov %eax,0x4(%esp) movl $0x804853a,(%esp) call 8048298 <printf@plt> leave ret 80483f2 : movl $0x0,0x4(%esp) movl $0x8048547,(%esp) call 8048298 <printf@plt> leave ret |
push %ebp mov %esp,%ebp sub $0x8,%esp mov 0x8(%ebp),%eax test %eax,%eax jne 80483b3 <FuncB+0x23> movl $0x0,0x4(%esp) movl $0x804852d,(%esp) call 8048298 <printf@plt> leave ret 80483b3 : shl $0x8,%eax mov %eax,0x4(%esp) movl $0x8048520,(%esp) call 8048298 <printf@plt> leave ret |