【转】gcc的__builtin_函数介绍

转自:http://blog.csdn.net/jasonchen_gbd/article/details/44948523

GCC提供了一系列的builtin函数,可以实现一些简单快捷的功能来方便程序编写,另外,很多builtin函数可用来优化编译结果。这些函数以“__builtin_”作为函数名前缀。
很多C标准库函数都有与之对应的GCC builtin函数,例如strcpy()有对应的__builtin_strcpy()内建函数。
下面就介绍一些builtin函数及其作用:

__builtin_ffs(x):返回x中最后一个为1的位是从后向前的第几位,如__builtin_ffs(0x789)=1, __builtin_ffs(0x78c)=3。于是,__builtin_ffs(x) - 1就是x中最后一个为1的位的位置。

__builtin_popcount(x):x中1的个数。

__builtin_ctz(x):x末尾0的个数。x=0时结果未定义。

__builtin_clz(x):x前导0的个数。x=0时结果未定义。

上面的宏中x都是unsigned int型的,如果传入signed或者是char型,会被强制转换成unsigned int。

__builtin_parity(x):x中1的奇偶性。

__builtin_return_address(n):当前函数的第n级调用者的地址,用的最多的就是__builtin_return_address(0),即获得当前函数的调用者的地址。注意,该函数实现是体系结构相关的,有些体系结构只实现了n=0的返回结果。

uint16_t __builtin_bswap16 (uint16_t x)

uint32_t __builtin_bswap32 (uint32_t x):按字节翻转x,返回翻转后的结果。

__builtin_prefetch (const void *addr, ...):它通过对数据手工预取的方法,在使用地址addr的值之前就将其放到cache中,减少了读取延迟,从而提高了性能,但该函数也需要 CPU 的支持。该函数可接受三个参数,第一个参数addr是要预取的数据的地址,第二个参数可设置为0或1(1表示我对地址addr要进行写操作,0表示要进行读操作),第三个参数可取0-3(0表示不用关心时间局部性,取完addr的值之后便不用留在cache中,而1、2、3表示时间局部性逐渐增强)。
__builtin_constant_p (exp):判断exp是否在编译时就可以确定其为常量,如果exp为常量,该函数返回1,否则返回0。如果exp为常量,可以在代码中做一些优化来减少处理exp的复杂度。
__builtin_types_compatible_p(type1, type2):判断type1和type2是否是相同的数据类型,相同返回1,否则返回0。该函数不区分const/volatile这样的修饰符,即int和const int被认为是相同的类型。

  1 #define foo(x)
  2 ({
  3 typeof(x) tmp = (x);  4 if(__builtin_types_compatible_p(typeof(x), int))  5 //do something...\
  6 else   7 //do something...\
  8 tmp;
  9 })

__builtin_expect (long exp, long c):用来引导gcc进行条件分支预测。在一条指令执行时,由于流水线的作用,CPU可以完成下一条指令的取指,这样可以提高CPU的利用率。在执行一条条件分支指令时,CPU也会预取下一条执行,但是如果条件分支跳转到了其他指令,那CPU预取的下一条指令就没用了,这样就降低了流水线的效率。内核中的likely()和unlikely()就是通过__builtin_expect来实现的。
__builtin_expect (long exp, long c)函数可以优化程序编译后的指令序列,使指令尽可能的顺序执行,从而提高CPU预取指令的正确率。该函数的第二个参数c可取0和1,
例如:

  1 if (__builtin_expect (x, 0))
  2             foo ();

表示x的值大部分情况下可能为0,因此foo()函数得到执行的机会比较少。gcc就不必将foo()函数的汇编指令紧挨着if条件跳转指令。
由于第二个参数只能取整数,所以如果要判断指针或字符串,可以像下面这样写:

  1 if (__builtin_expect (ptr != NULL, 1))
  2             foo (*ptr);

表示ptr一般不会为NULL,所以foo函数得到执行的概率较大,gcc会将foo函数的汇编指令放在挨着if跳转执行的位置。

时间: 2024-08-11 17:01:54

【转】gcc的__builtin_函数介绍的相关文章

gcc的__builtin_函数(注意前面是两个下划线)

说明: GCC provides a large number of built-in functions other than the ones mentioned above. Some of these are for internal use in the processing of exceptions or variable-length argument lists and will not be documented here because they may change fr

关于gcc内置函数和c隐式函数声明的认识以及一些推测

最近在看APUE,不愧是经典,看一点就收获一点.但是感觉有些东西还是没说清楚,需要自己动手验证一下,结果发现需要用gcc,就了解一下. 有时候,你在代码里面引用了一个函数但是没有包含相关的头文件,这个时候gcc报的错误比较诡异,一般是这样:[math.c:6:25: 警告:隐式声明与内建函数‘sin’不兼容 [默认启用]].这个错误网上大量博客都在说需要包含XXX.h文件,但是没有人解释这个错误信息为什么这样表达.什么是隐式声明,什么是内建函数,我就纠结了. 隐式声明函数的概念网上有相关的资料,

1.socket编程:socket编程,网络字节序,函数介绍,IP地址转换函数,sockaddr数据结构,网络套接字函数,socket相关函数,TCP server和client

 1  Socket编程 socket这个词可以表示很多概念: 在TCP/IP协议中,"IP地址+TCP或UDP端口号"唯一标识网络通讯中的一个进程,"IP 地址+端口号"就称为socket. 在TCP协议中,建立连接的两个进程各自有一个socket来标识,那么这两个socket组成的socket pair就唯一标识一个连接.socket本身有"插座"的意思,因此用来描述网络连 接的一对一关系. TCP/IP协议最早在BSD UNIX上实现,

GCC中初始化函数是如何被处理的?

本文译至: http://gcc.gnu.org/onlinedocs/gccint/Initialization.html 如我们所知,在GCC通过给代码追加__attribute__((constructor))和__attribute__((destructor))的方式可以追加初始函数和终止函数, 这篇文章介绍了GCC内部是如何实现上述处理的. 简单的说,就是在最经常的情况下,初始函数会被追加到.ctor section中,.init会调用对应的函数处理这些初始函数.终止情况类似. --

【C++】【lambda】lambda函数介绍和个人理解(3)——lambda的语法甜点

导航: lambda函数介绍和个人理解(1)--初识lambda lambda函数介绍和个人理解(2)--lambda与仿函数 lambda函数介绍和个人理解(3)--lambda的语法甜点 其实,与其说这是一篇介绍lambda语法甜点的文章,不如说是一篇教大家使用lambda函数的一篇文章.当然不可避免的会用到一些有趣的实验.文章略长,大家耐心耐心看吧!当然,这也是本人写的关于lambda函数的最后一篇博文了,如果大家有其他更好的想法或者更深入的理解,请联系我~ 本文大概讲这些内容:基础使用,

0-C相关01:NSlog函数介绍。

  NSlog()函数介绍: 首先:NSlog()函数是cocoa的框架中提供的一个方法: 下图中最上方是它在Xcode中的路径: : 同样都是输出函数.下边我们来看一下,在O-C中NSlog()和在 c 语言中的printf的一些不同: 1.nslog 和printf都可以输出字符串到控制台.@"1213244" @开头表示oc的字符串. 2.NSlog()在打印时能自带一次自动换行,后者没有,想换行需要\手动添加"\n".当然在NSlog()中也可以手动添加&q

VC和gcc在保证函数static变量线程安全性上的区别

VC和gcc不同,不能保证静态变量的线程安全性.这就给我们的程序带来了很大的安全隐患和诸多不便.这一点应该引起我们的重视!尤其是在构造函数耗时比较长的时候,很可能给程序带来意想不到的结果.本文从测试代码开始,逐步分析原理,最后给出解决方案. 多线程状态下,VC不能保证在使用函数的静态变量的时候,它的构造函数已经被执行完毕,下面是一段测试代码: class TestStatic { public: TestStatic() { Sleep(1000*10); m_num = 999; } publ

第16课-数据库开发及ado.net-数据库SQl,创建数据库和表,增删改语句,约束,top和Distinct,聚合函数介绍

第16课-数据库开发及ado.net 数据库SQl,创建数据库和表,增删改语句,约束,top和Distinct,聚合函数介绍 SQL语句入门(脚本.命令) SQL全名是结构化查询语言(Structured Query Language) SOL语句是和DBMS“交谈”专用的语言,不同的DBMS都认SQL语法. Sql中字符串使用单引号:通过写俩个单引号来转义一个单引号. Sql中的注释“——” 单行注释比较好 判断俩个数据是否相等使用=(单等号) 在sql语句中sql代码不区分大小写 SQL主要

JQuery AJAX函数介绍

jQuery 库拥有完整的 Ajax 兼容套件.其中的函数和方法允许我们在不刷新浏览器的情况下从服务器加载数据. 函数介绍 JOuery.ajax():执行异步HTTP(Ajax)请求. .ajaxComplete():当Ajax请求完成时注册要调用的处理程序.这是一个Ajax事件. .ajaxError:当Ajax请求完成且出现错误时注册要调用的处理程序.这是一个Ajax事件. .ajaxSend():在Ajax请求发送之前显示一条消息. jQuery.ajaxSetup():设置将来的Aja