在学习libev的过程中,遇到了大量的gcc内嵌函数,大多是为了提升性能而使用的,这里做一个汇总和介绍,持续更新
1、__builtin_expect
:该函数是gcc引入的,为的是让程序员讲最有可能执行的分支告诉编译器,达到性能提升的效果
源码:
//判断GNU版本号,如果不是gcc编译器,则不使用__builtin_expect函数
//否则如果主版本号大于major或者主版本号等于major但是次版本号大于minor则返回真 否则返回假
//__GNUC__ 、__GNUC_MINOR__ 、__GNUC_PATCHLEVEL__分别代表gcc的主版本号,次版本号,修正版本号。
//如果你的gcc版本为 6.7.8那么上述三个值依次为6 7 8 注意__GNUC_PATCHLEVEL__宏是gcc3.0后才出现的
#if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__
#define ECB_GCC_VERSION(major,minor) 0
#else
#define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
#endif
//判断clang编译器是否内置了某个功能
#if __clang__ && defined __has_builtin
#define ECB_CLANG_BUILTIN(x) __has_builtin (x)
#else
#define ECB_CLANG_BUILTIN(x) 0
#endif
//如果gcc版本号大于3.1,或者clang编译器内置了__builtin_expect,则使用该函数
#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_expect)
#define ecb_expect(expr,value) __builtin_expect ((expr),(value))
#else
//否则直接使用表达式判断
#define ecb_expect(expr,value) (expr)
#endif
//对__builtin_expect使用的一层封装
#define ecb_expect_false(expr) ecb_expect (!!(expr), 0)
//再次封装该函数,使命名看起来更加简单直观
#define expect_false(cond) ecb_expect_false (cond)
//终于到了逻辑层的使用
if (expect_false ((cnt) > (cur)))
作者的注释也是非常有趣,贴一段在判断编译器版本号时的注释,大意是骂"白痴"编译器作者实现的功能有限
/* many compilers define _GNUC_ to some versions but then only implement
* what their idiot authors think are the "more important" extensions,
* causing enormous grief in return for some better fake benchmark numbers.
* or so.
* we try to detect these and simply assume they are not gcc - if they have
* an issue with that they should have done it right in the first place.
*/