1. 程式人生 > >linux核心中:likely和unlikely函式

linux核心中:likely和unlikely函式

  核心原始碼:linux-2.6.38.8.tar.bz2

     在Linux核心中likely和unlikely函式有兩種(只能兩者選一)實現方式,它們的實現原理稍有不同,但作用是相同的,下面將結合linux-2.6.38.8版本的核心程式碼來進行講解。

    1、對__builtin_expect的封裝

    它們的原始碼如下: 

[cpp] view plaincopyprint?
  1. /* linux-2.6.38.8/include/linux/compiler.h */
  2. # define likely(x)  __builtin_expect(!!(x), 1)
  3. # define unlikely(x)    __builtin_expect(!!(x), 0)

    __builtin_expect 是GCC的內建函式,用來對選擇語句的判斷條件進行優化,常用於一個判斷條件經常成立(如likely)或經常不成立(如unlikely)的情況。

    __builtin_expect的函式原型為long  __builtin_expect (long exp, long c),返回值為完整表示式exp的值,它的作用是期望表示式exp的值等於c(注意,如果exp == c條件成立的機會佔絕大多數,那麼效能將會得到提升,否則效能反而會下降)。

    在普通的應用程式中也可以使用__builtin_expect,如下面的例子: 

[cpp] view plain
copyprint?
  1. #include <stdio.h>
  2. int main(void)  
  3. {  
  4. int a;  
  5.     scanf("%d", &a);  
  6. if(__builtin_expect(a, 4))  
  7.     printf("if: a = %d\n", a);  
  8. else
  9.     printf("else: a = %d\n", a);  
  10. return 0;  
  11. }  

    分別輸入整數0到4來進行5次測試,它們的輸出分別為: 

[cpp] view plaincopyprint?
  1. else: a = 0  
  2. if: a = 1  
  3. if: a = 2  
  4. if
    : a = 3  
  5. if: a = 4  

    注意,在上例中只有輸入整數0的時候才執行else後的列印語句,也就是說__builtin_expect(a, 4)函式的值就是表示式a的值。

    記住,它們只是用來提升效能的優化手段,並不會改變原來表示式的值。

    2、使用__branch_check__函式

    它們的原始碼如下: 

[cpp] view plaincopyprint?
  1. /* linux-2.6.38.8/include/linux/compiler.h */
  2. # ifndef likely
  3. #  define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))
  4. # endif
  5. # ifndef unlikely
  6. #  define unlikely(x)   (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
  7. # endif

    (1)先使用內建函式__builtin_constant_p忽略表示式x為常量的情況

    __builtin_constant_p也是GCC的內建函式,函式原型為int  __builtin_constant_p(exp),用於判斷表示式exp在編譯時是否是一個常量,如果是則函式的值為整數1,否則為0,如下面的例子:

[cpp] view plaincopyprint?
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define VALUE 5
  4. int main(void)  
  5. {  
  6. char *ptr = NULL;  
  7. int num, count;  
  8.     ptr = malloc(20);  
  9.     num = __builtin_constant_p(ptr) ? 20 : 20 + 10;  
  10.     printf("num = %d\n", num);  
  11.     free(ptr);  
  12.     count = __builtin_constant_p(VALUE) ? 20 + VALUE : 10;  
  13.     printf("count = %d\n", count);  
  14. return 0;  
  15. }  

    例子的輸出結果: 

[cpp] view plaincopyprint?
  1. num = 30  
  2. count = 25  

    例子中的ptr為指標變數,所以__builtin_constant_p(ptr)的值為0,num的值為30。

    (2)、函式__branch_check__的實現 

[cpp] view plaincopyprint?
  1. /* linux-2.6.38.8/include/linux/compiler.h */
  2. #define __branch_check__(x, expect) ({                  \
  3. int ______r;                    \  
  4. staticstruct ftrace_branch_data        \  
  5.                 __attribute__((__aligned__(4)))     \  
  6.                 __attribute__((section("_ftrace_annotated_branch"))) \  
  7.                 ______f = {             \  
  8.                 .func = __func__,           \  
  9.                 .file = __FILE__,           \  
  10.                 .line = __LINE__,           \  
  11.             };                      \  
  12.             ______r = likely_notrace(x);            \  
  13.             ftrace_likely_update(&______f, ______r, expect); \  
  14.             ______r;                    \  
  15.         })  

    使用它來檢查判斷條件並記錄likely判斷的預測資訊,之後根據預測資訊進行相應的優化以提升效能。

    函式__branch_check__的返回值為______r的值,也就是引數x的值。

相關推薦

linux心中likelyunlikely函式

  核心原始碼:linux-2.6.38.8.tar.bz2      在Linux核心中likely和unlikely函式有兩種(只能兩者選一)實現方式,它們的實現原理稍有不同,但作用是相同的,下面將結合linux-2.6.38.8版本的核心程式碼來進行講解。    

心中likelyunlikely巨集的使用

在核心程式碼中經常會看到unlikely和likely的蹤影。他們實際上是定義在 linux/compiler.h 中的兩個巨集。   #define likely(x) __builtin_expect(!!(x), 1)   #define unlikely(x) __

linux中宏likelyunlikely到底做了些什麽?

可能 3.3 png 通過 可能性 功能 clas 圖片 預測 1. 先看看它們長啥樣吧!(它們有兩種定義,第一種是使能了程序trace功能的宏定義,第二種是普通的宏定義,咱們分析普通宏定義吧) # define likely(x) __builtin_expect(

linux心中的copy_to_usercopy_from_user

Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csdn.net/ce123) 1.copy_from_user 在學習Linux核心驅動的時候,經常會碰到copy_from_user和c

詳解likelyunlikely函式【轉】

 核心原始碼:linux-2.6.38.8.tar.bz2      在Linux核心中likely和unlikely函式有兩種(只能兩者選一)實現方式,它們的實現原理稍有不同,但作用是相同的,下面將結合linux-2.6.38.8版本的核心程式碼來進行講解。

Linux心中的bsearch二分查詢函式

/* * bsearch - binary search an array of elements * @key: pointer to item being searched for * @base

linux心中GNU C標準C的區別

今天看了一下午的linux核心程式設計方面的內容,發現linux 核心中GNU C與標準C有一些差別,特記錄如下: linux 系統上可用的C編譯器是GNU C編譯器,它建立在自由軟體基金會的程式設計許可證的基礎上,因此可以自由釋出。GNU C對標準C進行進一步擴充套件,以增強標準C的功能。下面我們對GNU

Linux心中的kobjectkset介紹

本文會圍繞kobject、ktype和kset三個概念進行介紹,我們先大概瞭解一下相關概念以及它們之間的關係: kobject在核心中應用最多的就是裝置驅動模型————匯流排、裝置、驅動、類的管理都使用了kobject,但是kobject並不只為裝置驅動模型服

linux心中likelyunlikely的含義

在核心程式碼中經常會看到unlikely和likely的蹤影。他們實際上是定義在 linux/compiler.h 中的兩個巨集。   #define likely(x)    __builtin_ex

Linux 心中 likelyunlikely 的巨集定義解析

在 2.6 核心中,隨處可以見到 likely() 和 unlikely() 的身影,那麼為什麼要用它們?它們之間有什麼區別? 首先要明確: if(likely(value)) 等價於 if(value) if(unlikely(

linux心中的get userput user

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Linux 多工程式設計——多程序建立fork() vfork() 函式詳解

一、fork() 函式詳解 需要的標頭檔案: #include <sys/types.h> #include <unistd.h> pid_t fork(void); 功能: 用於從一個已存在的程序中建立一個新程序,新程序稱為子程序,原程序稱為父程序。

linux心中的GPIO系統之(1)軟體框架

一、前言作為一個工作多年的系統工程師,免不了做兩件事情:培訓新員工和給新員工分配任務。對於那些剛剛從學校出來的學生,一般在開始的時候總是分配一些非常簡單的任務,例如GPIO driver、LED driver。往往CPU datasheet的關於GPIO或者IO ports的

linux心中GPIO的使用(二)--標準介面函式

在linux核心中,有一些基本模組可以使用標準的介面函式來操作,比如GPIO、interrupt、clock,所謂的標準介面函式是指一些與硬體平臺無關的、linux下做驅動通用的函式, 常用的有: gpio_request();gpio_free()

armv8(aarch64)linux心中flush_dcache_all函式詳細分析

/* *  Flush the wholeD-cache.  * Corrupted registers: x0-x7, x9-x11  */ ENTRY(__flush_dcache_all

linux心中2410_gpio_cfgpin函式分析

2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT) 函式分析:作用設定相應GPIO口的工作模式,輸入、輸出、中斷等。 一,首先巨集展開:為方便描述,展開後用等號表示 #define S3C2410_GPIO

Linux心中trace_xxxx()函式的定義

Linux中trace_xxxx()函式的定義 以trace_netif_receive_skb(skb);為例 該函式的定義: 其中DEFINE_EVENT定義為(include/linux/

linuxlikely()unlikely()巨集

The gcc C compiler has a built-in directive that optimizes conditional branches as either very likely taken or very unlikely taken. The

linux中的likelyunlikely

文章來源:http://blog.csdn.net/tommy_wxie/article/details/7384641 看核心時總遇到if(likely( )){}或是if(unlikely( ))這樣的語句,最初不解其意,現在有所瞭解,所以也想介紹一下。 likely() 與 unlikely()是核心(

linux 開發】likelyunlikely用法及提升效率原理

1、具體定義如下,gcc 2.96以上版本支援 #define likely(x) __biltin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) 2、效率提升原理 #define likel