天天看點

libev中的gcc内嵌函數

在學習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.
 */