[转] GCC __builtin_expect的作用
http://blog.csdn.net/shuimuniao/article/details/8017971
将流水线引入cpu,可以提高cpu的效率。更简单的说,让cpu可以预先取出下一条指令,可以提供cpu的效率。如下图所示:
+--------------------------------
|取指令 | 执行指令 | 输出结果
+--------------------------------
| | 取指令 | 执行
+--------------------------------
可见,cpu流水钱可以减少cpu等待取指令的耗时,从而提高cpu的效率。
如果存在跳转指令,那么预先取出的指令就无用了。cpu在执行当前指令时,从内存中取出了当前指令的下一条指令。执行完当前指令后,cpu发现不是要执行
下一条指令,而是执行offset偏移处的指令。cpu只能重新从内存中取出offset偏移处的指令。因此,跳转指令会降低流水线的效率,也就是降低
cpu的效率。
综上,在写程序时应该尽量避免跳转语句。那么如何避免跳转语句呢?答案就是使用__builtin_expect。
这个指令是gcc引入的,作用是"允许程序员将最有可能执行的分支告诉编译器"。这个指令的写法为:__builtin_expect(EXP,
N)。意思是:EXP==N的概率很大。一般的使用方法是将__builtin_expect指令封装为LIKELY和UNLIKELY宏。这两个宏的写
法如下。
#define LIKELY(x) __builtin_expect(!!(x), 1) //x很可能为真
#define UNLIKELY(x) __builtin_expect(!!(x), 0) //x很可能为假
如下是一个实际的例子。
- //test_builtin_expect.c
- #define LIKELY(x) __builtin_expect(!!(x), 1)
- #define UNLIKELY(x) __builtin_expect(!!(x), 0)
- int test_likely(int x)
- {
- if(LIKELY(x))
- {
- x = 5;
- }
- else
- {
- x = 6;
- }
- return x;
- }
- int test_unlikely(int x)
- {
- if(UNLIKELY(x))
- {
- x = 5;
- }
- else
- {
- x = 6;
- }
- return x;
- }
运行如下命令:
gcc -fprofile-arcs -O2 -c test_builtin_expect.c
objdump -d test_builtin_expect.o
输出的汇编码为:
- <test_likely>:
- 00 push %ebp
- 01 mov %esp,%ebp
- 03 mov 0x8(%ebp),%eax
- 06 addl $0x1,0x38
- 0d adcl $0x0,0x3c
- 14 test %eax,%eax
- 16 jz 2d <test_likely+0x2d>//主要看这里。此处的效果是eax不为零时,不需要跳转。即x为真是不跳转。
- 18 addl $0x1,0x40
- 1f mov $0x5,%eax
- 24 adcl $0x0,0x44
- 2b pop %ebp
- 2c ret
- 2d addl $0x1,0x48
- 34 mov $0x6,%eax
- 39 adcl $0x0,0x4c
- 40 pop %ebp
- 41 ret
- 42 lea 0x0(%esi,%eiz,1),%esi
- 49 lea 0x0(%edi,%eiz,1),%edi
- <test_unlikely>:
- 50 push %ebp
- 51 mov %esp,%ebp
- 53 mov 0x8(%ebp),%edx
- 56 addl $0x1,0x20
- 5d adcl $0x0,0x24
- 64 test %edx,%edx
- 66 jne 7d <test_unlikely+0x2d>//主要看这里。此处的效果是edx为零时,不需跳转。即x为假时不跳转。
- 68 addl $0x1,0x30
- 6f mov $0x6,%eax
- 74 adcl $0x0,0x34
- 7b pop %ebp
- 7c ret
- 7d addl $0x1,0x28
- 84 mov $0x5,%eax
- 89 adcl $0x0,0x2c
- 90 pop %ebp
- 91 ret
- 92 lea 0x0(%esi,%eiz,1),%esi
- 99 lea 0x0(%edi,%eiz,1),%edi
可见,编译器利用程序员作出的判断,生成了高效的汇编码。即,跳转语句不生效的概率很大。
参考资料:http://hi.baidu.com/uu_dou/item/e9f6f41d570d817b7a5f25c7
[转] GCC __builtin_expect的作用的更多相关文章
- GCC __builtin_expect的作用
https://blog.csdn.net/shuimuniao/article/details/8017971 #define LIKELY(x) __builtin_expect(!!(x), 1 ...
- gcc -ldl 选项作用
如果你的程序中使用dlopen.dlsym.dlclose.dlerror 显示加载动态库,需要设置链接选项 -ldl 加载动态链接库,首先为共享库分配物理内存,然后在进程对应的页表项中建立虚拟页和物 ...
- Clang比 gcc/g++更人性化代码出错提示的C/C++编译器
编译器方面的几个命令 gcc/g++ 一. 常用编译命令选项 常用用法 gcc -Wall test.c -o test gcc编译过程 .c ->(-E)-> .i[中间文件] -> ...
- linux下gcc编译多个源文件、gdb的使用方法
一. gcc常用编译命令选项 假设源程序文件名为test.c. 1. 无选项编译链接 用法:#gcc test.c 作用:将test.c预处理.汇编.编译并链接形成可执行文件.这里未指定输出文件,默认 ...
- gcc编译代码报错及编译方式
一.error: 'for' loop initial declarations are only allowed in C99 mode 前段时间写了一个小C程序,放在linux下用gcc编译出错, ...
- GCC 编译命令
今天突然被同事问道一个GCC编译命令为的问题,感觉对相应内容生疏了,赶紧整理下相关内容,梳理下相关知识. GCC命令提供了非常多的命令选项,但并不是所有都要熟悉,初学时掌握几个常用的就可以了,到后面再 ...
- Ubuntu下GCC的安装以及版本控制
在Ubuntu下安装GCC和其他一些Linux系统有点不一样. 方法一: 该方法超简单:sudo apt-get build-depgcc 就上面这条命令就可以搞定 方法二:sudo apt-get ...
- gcc总结【基本用法】【选项】【动静态库】(转)
1.////////////////////////////////////////////////////////////////////////////////////////////////// ...
- gcc常用命令集
引用:http://developer.51cto.com/art/200609/32317_1.htm 对于GUN编译器来说,程序的编译要经历预处理.编译.汇编.连接四个阶段 假设源程序文件名为te ...
随机推荐
- 最大乘积(Maximum Product,UVA 11059)
Problem D - Maximum Product Time Limit: 1 second Given a sequence of integers S = {S1, S2, ..., Sn}, ...
- 提供进销存、ERP系统快速开发框架源码 (C#+SQL)
C/S系统开发框架-企业版 V4.0 (Enterprise Edition) 简介: http://www.csframework.com/cs-framework-4.0.htm 视频下载: 百度 ...
- python中对文件、文件夹的操作需要涉及到os模块和shutil模块。
创建文件:1) os.mknod("test.txt") 创建空文件2) open("test.txt",w) 直接打开一个文件,如果文件不存在则创建文件 创建 ...
- SharePoint2013 Powershell script to get site Title, Site Owner, Site user count and usage
Powershell script to get site Title, Site Owner, Site user count and usage Add-PSSnapin microsoft.sh ...
- ubuntu進入dos界面命令 ubuntu進入圖形界面命令
切换界面: ctrl + alt + F1是切到终端模式 Alt+F7 切到图形界面
- hdu 5063 Operation the Sequence
http://acm.hdu.edu.cn/showproblem.php?pid=5063 思路:因为3查询最多50,所以可以在查询的时候逆操作找到原来的位置,然后再求查询的值. #include ...
- LINUX-LXC要好好关注下
因为我觉得轻量极虚拟化可能是云的另一个发展方向. 至少,腾讯的WEB云引擎是以此为基础. LXC结合DOCKER.相信是快速云的另一种实现. 余下的,只是结合生产系统围绕这一中心进行的的二次开了. I ...
- sql server 发布时提示'dbo.sysmergepublications'无效的解决办法
对数据库进行数据库复制.订阅时经常会出现各种奇怪的问题 如果你对数据库进行多次发布.删除发布操作时可能会提示“dbo.sysmergepublications”无效的问题, 可以使用以下方法解决: U ...
- Unity Time的使用
脚本语言:C# 1.deltatime: deltatime它表示距上一次调用Update或FixedUpdate所用的时间,调用deltatime可以使物体的旋转以一种恒定的速度来运行,而不受帧速率 ...
- BZOJ1044: [HAOI2008]木棍分割
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1580 Solved: 567[Submit][Statu ...