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