【ARM 嵌入式 编译系列 5 -- GCC 内建函数 __builtin 详细介绍】


请阅读【ARM GCC 编译专栏导读】

上篇文章:ARM 嵌入式 编译系列 4.2 – GCC 链接规范 extern “C“ 介绍
下篇文章:ARM 嵌入式 编译系列 6 – GCC objcopy, objdump, readelf, nm 介绍

什么是GCC内建函数?

GCC提供了一些专门的功能,用于访问特定的硬件指令或者实现特定的优化,它们被称为"__builtin"函数。

这些函数在语法上看起来像是普通函数,但在编译阶段会被编译器直接转换为一些特定的机器指令,而不是像普通函数那样调用通用的函数调用协议。

GCC提供的__builtin函数非常多,包括了数学函数字符串操作内存操作位操作类型转换计数前导零/尾零CPU指定指令等等功能。

使用__builtin函数可以在不牺牲可读性的同时获得更高的性能。但是请注意,由于这些函数直接对应特定的硬件指令,所以在不同的硬件和操作系统上,它们的效果和性能可能会有所不同。因此,在编写依赖于__builtin函数的代码时,需要特别注意移植性的问题。

要在GCC中使用__builtin函数,只需要在代码中直接调用即可,无需包含任何头文件。

GCC 常见内建函数

GCC编译器提供了很多内建函数,这些函数可以帮助我们进行一些特殊的操作,以下是一些常见的GCC内建函数:

  • __builtin_expect:提供编译器关于一个条件判断表达式结果的预期值,用于优化代码, 见likelyunlikely的实现;

  • __builtin_clz:计算无符号整数的前导零的数量;

  • __builtin_ctz:计算无符号整数的尾随零的数量;

  • __builtin_popcount:计算二进制表示中1的个数;

  • __builtin_types_compatible_p:在编译期检查两个类型是否兼容;

  • __builtin_offsetof:获取结构体成员在结构体中的偏移量;

  • __builtin_prefetch:预先把数据加载到缓存,用于提高程序运行效率;

  • __builtin_return_address:获取返回地址,常用于调试;

  • __builtin_frame_address:获取当前函数调用栈帧的地址;

  • __builtin_choose_expr:在编译期进行条件选择。

以上只是GCC内建函数的一部分,GCC还提供了许多其他的内建函数。这些内建函数都是在编译期间执行,因此它们不能用于运行时的计算。同时,由于这些函数是编译器提供的,所以它们的行为可能会随着编译器的版本和目标平台的不同而有所变化

GCC内建函数使用示例

以下为一些GCC内建函数的使用示例:

  • __builtin_expect
if (__builtin_expect(x > 0, 1)) 
{ 
	//大部分情况下,x > 0 
} else { 
	//其他情况 
}
  • __builtin_clz
unsigned int x = 16; 
int leading_zero = __builtin_clz(x); // 结果为 27
  • __builtin_ctz
unsigned int x = 16; 
int trailing_zero = __builtin_ctz(x); // 结果为 4
  • __builtin_popcount
unsigned int x = 15; 
int count_one = __builtin_popcount(x); // 结果为 4
  • __builtin_offsetof
struct S {
	int x; 
	double y; 
}; 

size_t offset = __builtin_offsetof(struct S, y); // 结果为 sizeof(int)
  • __builtin_prefetch
int array[100]; 
__builtin_prefetch(&array[50], 0, 0); 

// ... 其他代码 ... 
int data = array[50]; // 这个读取操作可能会更快,因为数据可能已经在缓存中

以上只是简单示例,实际应用中可能需要根据具体情况调整使用方式。

由于__builtin函数是GCC特有的扩展,所以如果你的代码需要在其他编译器(如Clang、MSVC等)上编译,那么可能需要提供相应的兼容代码。对于这种情况,GCC也提供了一些预处理宏,可以用来检查当前编译器是否支持__builtin函数。例如:

#ifdef __GNUC__ 
	int clz = __builtin_clz(42); 
#else 
	// 提供一个备用的实现 
	int clz = fallback_clz(42); 
#endif

总的来说,__builtin函数是GCC提供的一种强大的工具,可以在需要的时候用来提高代码的性能。但是,由于它们的移植性问题,所以在使用时需要谨慎。

上篇文章:ARM 嵌入式 编译系列 4.2 – GCC 链接规范 extern “C“ 介绍
下篇文章:ARM 嵌入式 编译系列 6 – GCC objcopy, objdump, readelf, nm 介绍

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

主公CodingCos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值