C语言内建函数:__builtin_XXX
首先内建函数有的属于预编译,有的属于运行过程的函数,这一点我现在还不是很清楚,待以后进一步详细讨论。
然后我们给出一个长代码,里面包含了常用的C语言内建函数,参考文章见文末。
总览:
- __builtin_ffs(s);
- __builtin_popcount(s);
- __builtin_ctz(s);
- __builtin_clz(s);
- __builtin_parity(i);
- __builtin_return_address(s);
- __builtin_bswap16(i);
- __builtin_bswap32(i);
- __builtin_prefetch(const void *addr, ...);
- __builtin_constant_p(exp);
- __builtin_types_compatible_p(t1, t2);
- __builtin_expect(exp, c);
#include <stdio.h>
#include <stdarg.h>/*** 返回x中最后一个为1的位是从后向前的第几位* 000101000 -> 4* 8 -> 4*/
#define ffs(s) __builtin_ffs(s)/*** x中1的个数**/
#define popcount(s) __builtin_popcount(s)/*** x末尾0的个数。x=0时结果未定义。* x前导0的个数。x=0时结果未定义。*/
#define ctz(s) __builtin_ctz(s)
#define clz(s) __builtin_clz(s)/*** x中1的奇偶性。* 奇:1, 偶:0*/
#define parity(i) __builtin_parity(i)/*** 当前函数的第n级调用者的地址,用的最多的就是__builtin_return_address(0),* 即获得当前函数的调用者的地址。* 注意,该函数实现是体系结构相关的,有些体系结构只实现了n=0的返回结果。*/
#define return_addr(s) __builtin_return_address(s)void test1_return_address(){printf("%s: %p\n", __func__, return_addr(1));}
void test2_return_address(){test1_return_address(); printf("%s: %p\n", __func__, return_addr(0));}
void test3_return_address(){test2_return_address(); printf("%s: %p\n", __func__, return_addr(0));}/*** 按字节翻转x,返回翻转后的结果。* uint16_t __builtin_bswap16 (uint16_t x)* uint32_t __builtin_bswap32 (uint32_t x)*/
#define swap16(i) __builtin_bswap16(i)
#define swap32(i) __builtin_bswap32(i)/*** 它通过对数据手工预取的方法,在使用地址addr的值之前就将其放到cache中,* 减少了读取延迟,从而提高了性能,但该函数也需要 CPU 的支持。* 该函数可接受三个参数,* 第一个参数addr是要预取的数据的地址,* 第二个参数可设置为0或1(1表示我对地址addr要进行写操作,0表示要进行读操作),* 第三个参数可取0-3(0表示不用关心时间局部性,取完addr的值之后便不用留在cache中,* 而1、2、3表示时间局部性逐渐增强)。* __builtin_prefetch (const void *addr, ...)*/
#define prefetch(...) __builtin_prefetch(__VA_ARGS__)/*** 判断exp是否在编译时就可以确定其为常量,* 如果exp为常量,该函数返回1,否则返回0。* 如果exp为常量,可以在代码中做一些优化来减少处理exp的复杂度*/
#define constant_p(exp) __builtin_constant_p(exp)
#define CONST_P 123/*** 判断type1和type2是否是相同的数据类型,相同返回1,否则返回0。* 该函数不区分const/volatile这样的修饰符,即int和const int被认为是相同的类型*/
#define types_cmp_p(t1, t2) __builtin_types_compatible_p(t1, t2)#if 0
#define foo(x) \
typeof(x) tmp = (x);\
if(__builtin_types_compatible_p(typeof(x), int))\
//do something...\
else \
//do something...\
tmp;
#endif //0/*** 用来引导gcc进行条件分支预测。在一条指令执行时,由于流水线的作用,* CPU可以完成下一条指令的取指,这样可以提高CPU的利用率。* 在执行一条条件分支指令时,CPU也会预取下一条执行,但是如果条件分支跳转到了其他指令,* 那CPU预取的下一条指令就没用了,这样就降低了流水线的效率。* 内核中的likely()和unlikely()就是通过__builtin_expect来实现的。* __builtin_expect (long exp, long c)函数可以优化程序编译后的指令序列,* 使指令尽可能的顺序执行,从而提高CPU预取指令的正确率。该函数的第二个参数c可取0和1,*/
#define except(exp, c) __builtin_expect(exp, c)
#define likely(x) __builtin_expect(!!x, 1)
#define unlikely(x) __builtin_expect(!!x, 0)int main()
{int i = 0x03f8;printf("%d, %d, %d, %d\n", ffs(i), popcount(i), ctz(i), clz(i));printf("%d\n", parity(i));printf("main: %p\n", main);test3_return_address();printf("%x, %x\n", i, swap32(i));prefetch(&i, 0, 2);printf("%p\n", &i);printf("constant: %d\n", constant_p(CONST_P));printf("constant: %d\n", constant_p(i));int j;printf("type cmp: %d\n", types_cmp_p(typeof(j), typeof(i))); if(likely(i))printf("likely:%ld, %d\n", likely(i), i);return 0;
}
/**https://blog.csdn.net/jasonchen_gbd/article/details/44948523*/
作者:落尘纷扰
来源:CSDN
原文:https://blog.csdn.net/jasonchen_gbd/article/details/44948523
版权声明:本文为博主原创文章,转载请附上博文链接!
C语言内建函数:__builtin_XXX相关推荐
- 结构体构造函数_Go 语言的数据结构 :栈与队列
在先前的博文中,我们探讨了链表以及如何将它应用于实际应用.在这篇文章中,我们将继续探讨两个相似且功能强大的数据结构. 建模操作和历史 让我们看看 Excel 或 Google 文档,他们是人类发明的最 ...
- go waitgroup.done()异常处理_Go 异常处理
运行时恐慌 panic 这种程序异常叫做 panic,我们把它翻译成运行时恐慌.其中恐慌是由 panic 直译过来的,之所以加上运行时是因为这种异常只会在程序运行时的时候抛出来. package ma ...
- 【嵌入式】C语言高级编程-内建函数(11)
00. 目录 文章目录 00. 目录 01. 内建函数概述 02. 常用内建函数 03. C 标准库的内建函数 04. 内核中的 likely 和 unlikely 05. 附录 01. 内建函数概述 ...
- freeMarker(十)——模板语言之内建函数
学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 1.字符串内建函数 这些内建函数作用于表达式左侧的字符串值. 如果左侧 ...
- 嵌入式C语言自我修养 (11):有一种函数,叫内建函数
11.1 什么是内建函数 内建函数,顾名思义,就是编译器内部实现的函数.这些函数跟关键字一样,可以直接使用,无须像标准库函数那样,要 #include 对应的头文件才能使用. 内建函数的函数命名,通常 ...
- 图片处理之着色器语言 GLSL (opengl-shader-language) 内建函数
内建函数基本上可以分为一下三类: (1)它们使用一些简便的方式提供必要的硬件功能,如材质贴图.这些函数单独通过着色器是无法模拟出来的. (2)它们展示了一些可以常简单的写入的繁琐操作(clamp, m ...
- 2.4 Go语言基础之切片
本文主要介绍Go语言中切片(slice)及它的基本使用. 一.引子 因为数组的长度是固定的并且数组长度属于类型的一部分,所以数组有很多的局限性. 例如: func arraySum(x [3]int) ...
- mooc python_MOOC python笔记(一):python语言概述
python语言简介 特点:简单.易学.使用者多. 荷兰人Guido 1989年发明. 面向对象的解释型计算机程序设计语言. 设计哲学是"优雅"."明确".&q ...
- MaxCompute - ODPS重装上阵 第二弹 - 新的基本数据类型与内建函数
MaxCompute(原ODPS)是阿里云自主研发的具有业界领先水平的分布式大数据处理平台, 尤其在集团内部得到广泛应用,支撑了多个BU的核心业务. MaxCompute除了持续优化性能外,也致力于提 ...
最新文章
- 【转】ASP.NET Page事件的执行顺序
- linux安装ffmpeg
- caffe中通过prototxt文件查看神经网络模型结构的方法
- 使用Stream流的方式,遍历集合,对集合中的数据进行过滤
- 深度学习为图片压缩算法赋能:节省55%带宽
- C语言中指针的初始化和赋值
- Gartner:6个容器和Kubernetes策略的最佳实用技巧
- mysql数据库新建一个递增的_分享一个mysql实验—基于数据库事务隔离级别RR及RC的测试...
- aspen变压吸附塔_空压机科普:吸附式干燥机的结构和原理
- mysql表结构定义_Mysql表结构定义及相关语法
- hdu 1247 Hat’s Words 字典树
- 计算机abcd地址,IP地址ABCDE的分类说明
- java笔试涉及编程题
- html5局部放大图片,图片局部放大效果原理详解
- 虚拟机运行python_虚的解释|虚的意思|汉典“虚”字的基本解释
- vue 如何做到图片预览
- html制作雪花飘落海报,HTML5 canvas实现雪花飘落特效
- 通过企业微信或者微信公众号发送小程序消息推送功能
- Ubuntu18.04+KinectV1(XBOX360)+ORB_SLAM2
- 如何轻松愉快的搞定产品经理面试