linux核心中:likely和unlikely函式
在Linux核心中likely和unlikely函式有兩種(只能兩者選一)實現方式,它們的實現原理稍有不同,但作用是相同的,下面將結合linux-2.6.38.8版本的核心程式碼來進行講解。
1、對__builtin_expect的封裝
它們的原始碼如下:
[cpp] view plaincopyprint?- /* linux-2.6.38.8/include/linux/compiler.h */
- # define likely(x) __builtin_expect(!!(x), 1)
- # 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- #include <stdio.h>
- int main(void)
- {
- int a;
- scanf("%d", &a);
- if(__builtin_expect(a, 4))
- printf("if: a = %d\n", a);
- else
- printf("else: a = %d\n", a);
- return 0;
- }
分別輸入整數0到4來進行5次測試,它們的輸出分別為:
[cpp] view plaincopyprint?- else: a = 0
- if: a = 1
- if: a = 2
- if
- if: a = 4
注意,在上例中只有輸入整數0的時候才執行else後的列印語句,也就是說__builtin_expect(a, 4)函式的值就是表示式a的值。
記住,它們只是用來提升效能的優化手段,並不會改變原來表示式的值。
2、使用__branch_check__函式
它們的原始碼如下:
[cpp] view plaincopyprint?- /* linux-2.6.38.8/include/linux/compiler.h */
- # ifndef likely
- # define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))
- # endif
- # ifndef unlikely
- # define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
- # endif
(1)先使用內建函式__builtin_constant_p忽略表示式x為常量的情況
__builtin_constant_p也是GCC的內建函式,函式原型為int __builtin_constant_p(exp),用於判斷表示式exp在編譯時是否是一個常量,如果是則函式的值為整數1,否則為0,如下面的例子:
[cpp] view plaincopyprint?- #include <stdio.h>
- #include <stdlib.h>
- #define VALUE 5
- int main(void)
- {
- char *ptr = NULL;
- int num, count;
- ptr = malloc(20);
- num = __builtin_constant_p(ptr) ? 20 : 20 + 10;
- printf("num = %d\n", num);
- free(ptr);
- count = __builtin_constant_p(VALUE) ? 20 + VALUE : 10;
- printf("count = %d\n", count);
- return 0;
- }
例子的輸出結果:
[cpp] view plaincopyprint?- num = 30
- count = 25
例子中的ptr為指標變數,所以__builtin_constant_p(ptr)的值為0,num的值為30。
(2)、函式__branch_check__的實現
[cpp] view plaincopyprint?- /* linux-2.6.38.8/include/linux/compiler.h */
- #define __branch_check__(x, expect) ({ \
- int ______r; \
- staticstruct ftrace_branch_data \
- __attribute__((__aligned__(4))) \
- __attribute__((section("_ftrace_annotated_branch"))) \
- ______f = { \
- .func = __func__, \
- .file = __FILE__, \
- .line = __LINE__, \
- }; \
- ______r = likely_notrace(x); \
- ftrace_likely_update(&______f, ______r, expect); \
- ______r; \
- })
使用它來檢查判斷條件並記錄likely判斷的預測資訊,之後根據預測資訊進行相應的優化以提升效能。
函式__branch_check__的返回值為______r的值,也就是引數x的值。
相關推薦
linux核心中:likely和unlikely函式
核心原始碼:linux-2.6.38.8.tar.bz2 在Linux核心中likely和unlikely函式有兩種(只能兩者選一)實現方式,它們的實現原理稍有不同,但作用是相同的,下面將結合linux-2.6.38.8版本的核心程式碼來進行講解。
核心中的likely和unlikely巨集的使用
在核心程式碼中經常會看到unlikely和likely的蹤影。他們實際上是定義在 linux/compiler.h 中的兩個巨集。 #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __
linux內核中宏likely和unlikely到底做了些什麽?
可能 3.3 png 通過 可能性 功能 clas 圖片 預測 1. 先看看它們長啥樣吧!(它們有兩種定義,第一種是使能了程序trace功能的宏定義,第二種是普通的宏定義,咱們分析普通宏定義吧) # define likely(x) __builtin_expect(
linux核心中的copy_to_user和copy_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
詳解likely和unlikely函式【轉】
核心原始碼: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核心中的kobject和kset介紹
本文會圍繞kobject、ktype和kset三個概念進行介紹,我們先大概瞭解一下相關概念以及它們之間的關係: kobject在核心中應用最多的就是裝置驅動模型————匯流排、裝置、驅動、類的管理都使用了kobject,但是kobject並不只為裝置驅動模型服
linux核心中likely和unlikely的含義
在核心程式碼中經常會看到unlikely和likely的蹤影。他們實際上是定義在 linux/compiler.h 中的兩個巨集。 #define likely(x) __builtin_ex
Linux 核心中 likely 與 unlikely 的巨集定義解析
在 2.6 核心中,隨處可以見到 likely() 和 unlikely() 的身影,那麼為什麼要用它們?它們之間有什麼區別? 首先要明確: if(likely(value)) 等價於 if(value) if(unlikely(
linux核心中的get user和put 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/
linux中likely()和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中的likely和unlikely
文章來源:http://blog.csdn.net/tommy_wxie/article/details/7384641 看核心時總遇到if(likely( )){}或是if(unlikely( ))這樣的語句,最初不解其意,現在有所瞭解,所以也想介紹一下。 likely() 與 unlikely()是核心(
【linux 開發】likely和unlikely用法及提升效率原理
1、具體定義如下,gcc 2.96以上版本支援 #define likely(x) __biltin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) 2、效率提升原理 #define likel