C/C++ 分支预测(likely unlikely)

看一些代码时,会遇到likely unlikely, 查了查网上的资料,结合自己的理解记录一下。

1. 一些概念

  指令周期是指执行一条指令所需要的时间,一般由若干个机器周期组成,是从取指令、分析指令到指令执行完所需的全部。

  预取指令具体方法就是在不命中时,当数据从主存储器中取出送往CPU的同时,把主存储器相邻几个单元中的数据(称为一个数据块)都取出来送入Cache中。预取指令可以更好的利用 cpu资源。简单说就是从内存取指令很慢, cpu要等待这个过程。如果能提前预测可能执行的指令,就提前从内存把指令读到 cache, 由于 cache的访问速度较内存快,cpu要执行时就不用等很长时间了。

  如果开发人员可以告诉编译器,哪个分支更有可能发生(likely) 或者 非常不可能发生(unlikely), 可以帮助编译器进行代码编译

2. 看看代码

unlikely.cpp:

 1 #include
 2 #include
 3 
 4 #define likely(x) __builtin_expect(!!(x), 1) //gcc内置函数, 帮助编译器分支优化
 5 #define unlikely(x) __builtin_expect(!!(x), 0)
 6 
 7 int main(int argc, char* argv[]){
 8     int x = 0;
 9     x = atoi(argv[1]);
10 
11     if (unlikely(x == 3)){  //告诉编译器这个分支非常不可能为true
12         x = x + 9;
13     }
14     else{
15         x = x - 8;
16     }
17 
18     printf("x=%d\n", x);
19     return 0;
20 }

3. 分析一下

gcc版本:gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

编译:gcc -O2 unlikely.cpp -o unlikely

反汇编一下,看看汇编:objdump -S unlikely

 1 08048380 
: 2 8048380: 55 push %ebp 3 8048381: 89 e5 mov %esp,%ebp 4 8048383: 83 e4 f0 and $0xfffffff0,%esp 5 8048386: 83 ec 10 sub $0x10,%esp 6 8048389: 8b 45 0c mov 0xc(%ebp),%eax 7 804838c: c7 44 24 08 0a 00 00 movl $0xa,0x8(%esp) 8 8048393: 00 9 8048394: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) 10 804839b: 00 11 804839c: 8b 40 04 mov 0x4(%eax),%eax 12 804839f: 89 04 24 mov %eax,(%esp) 13 80483a2: e8 c9 ff ff ff call 8048370 14 80483a7: 83 f8 03 cmp $0x3,%eax 15 80483aa: 74 1f je 80483cb 16 80483ac: 83 e8 08 sub $0x8,%eax 17 80483af: 89 44 24 08 mov %eax,0x8(%esp) 18 80483b3: c7 44 24 04 60 85 04 movl $0x8048560,0x4(%esp) 19 80483ba: 08 20 80483bb: c7 04 24 01 00 00 00 movl $0x1,(%esp) 21 80483c2: e8 99 ff ff ff call 8048360 <__printf_chk@plt> 22 80483c7: 31 c0 xor %eax,%eax 23 80483c9: c9 leave 24 80483ca: c3 ret 25 80483cb: b8 0c 00 00 00 mov $0xc,%eax 26 80483d0: eb dd jmp 80483af 27 80483d2: 90 nop 28 80483d3: 90 nop

 我们从汇编代码可以看到,代码并不是按照顺序生成的。

unlikely分支(x==3)非常不可能发生,汇编代码生成到了最后。

这个对于庞大的代码还是非常有用的,毕竟在代码预期阶段,可以根据局部性原理把最可能发生的分支对应的指令缓存进来。

你可能感兴趣的:(C/C++ 分支预测(likely unlikely))