1. 程式人生 > >【轉】gcc的__builtin_函數介紹

【轉】gcc的__builtin_函數介紹

部分 art types 字節 函數的調用 編寫 強制 跳轉指令 預取

轉自:http://blog.csdn.net/jasonchen_gbd/article/details/44948523

GCC提供了一系列的builtin函數,可以實現一些簡單快捷的功能來方便程序編寫,另外,很多builtin函數可用來優化編譯結果。這些函數以“__builtin_”作為函數名前綴。
很多C標準庫函數都有與之對應的GCC builtin函數,例如strcpy()有對應的__builtin_strcpy()內建函數。
下面就介紹一些builtin函數及其作用:

__builtin_ffs(x):返回x中最後一個為1的位是從後向前的第幾位,如__builtin_ffs(0x789)=1, __builtin_ffs(0x78c)=3。於是,__builtin_ffs(x) - 1就是x中最後一個為1的位的位置。

__builtin_popcount(x):x中1的個數。

__builtin_ctz(x):x末尾0的個數。x=0時結果未定義。

__builtin_clz(x):x前導0的個數。x=0時結果未定義。

上面的宏中x都是unsigned int型的,如果傳入signed或者是char型,會被強制轉換成unsigned int。

__builtin_parity(x):x中1的奇偶性。

__builtin_return_address(n):當前函數的第n級調用者的地址,用的最多的就是__builtin_return_address(0),即獲得當前函數的調用者的地址。註意,該函數實現是體系結構相關的,有些體系結構只實現了n=0的返回結果。

uint16_t __builtin_bswap16 (uint16_t x)

uint32_t __builtin_bswap32 (uint32_t x):按字節翻轉x,返回翻轉後的結果。

__builtin_prefetch (const void *addr, ...):它通過對數據手工預取的方法,在使用地址addr的值之前就將其放到cache中,減少了讀取延遲,從而提高了性能,但該函數也需要 CPU 的支持。該函數可接受三個參數,第一個參數addr是要預取的數據的地址,第二個參數可設置為0或1(1表示我對地址addr要進行寫操作,0表示要進行讀操作),第三個參數可取0-3(0表示不用關心時間局部性,取完addr的值之後便不用留在cache中,而1、2、3表示時間局部性逐漸增強)。
__builtin_constant_p (exp)

:判斷exp是否在編譯時就可以確定其為常量,如果exp為常量,該函數返回1,否則返回0。如果exp為常量,可以在代碼中做一些優化來減少處理exp的復雜度。
__builtin_types_compatible_p(type1, type2):判斷type1和type2是否是相同的數據類型,相同返回1,否則返回0。該函數不區分const/volatile這樣的修飾符,即int和const int被認為是相同的類型。

  1 #define foo(x)
  2 ({
  3 typeof(x) tmp = (x);  4 if(__builtin_types_compatible_p(typeof(x), int))  5 //do something...\
  6 else   7 //do something...\
  8 tmp;
  9 })

__builtin_expect (long exp, long c):用來引導gcc進行條件分支預測。在一條指令執行時,由於流水線的作用,CPU可以完成下一條指令的取指,這樣可以提高CPU的利用率。在執行一條條件分支指令時,CPU也會預取下一條執行,但是如果條件分支跳轉到了其他指令,那CPU預取的下一條指令就沒用了,這樣就降低了流水線的效率。內核中的likely()和unlikely()就是通過__builtin_expect來實現的。
__builtin_expect (long exp, long c)函數可以優化程序編譯後的指令序列,使指令盡可能的順序執行,從而提高CPU預取指令的正確率。該函數的第二個參數c可取0和1,
例如:
  1 if (__builtin_expect (x, 0))
  2             foo ();

表示x的值大部分情況下可能為0,因此foo()函數得到執行的機會比較少。gcc就不必將foo()函數的匯編指令緊挨著if條件跳轉指令。
由於第二個參數只能取整數,所以如果要判斷指針或字符串,可以像下面這樣寫:
  1 if (__builtin_expect (ptr != NULL, 1))
  2             foo (*ptr);

表示ptr一般不會為NULL,所以foo函數得到執行的概率較大,gcc會將foo函數的匯編指令放在挨著if跳轉執行的位置。

【轉】gcc的__builtin_函數介紹