1. 程式人生 > >linux中 likely與unlikely

linux中 likely與unlikely

轉自  http://blog.csdn.net/tommy_wxie/article/details/7384641

看核心時總遇到if(likely( )){}或是if(unlikely( ))這樣的語句,最初不解其意,現在有所瞭解,所以也想介紹一下。


likely() 與 unlikely()是核心(我看的是2.6.22.6版本,2.6的版本應該都有)中定義的兩個巨集。位於/include/linux/compiler.h中,
具體定義如下:
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)


__builtin_expect是gcc(版本>=2.96,網上寫的,我沒驗證過)中提供的一個預處理命令(這個名詞也是網上寫的,我想叫函式更好些),有利於程式碼優化。gcc(version 4.4.0)具體定義如下:
long __builtin_expect (long exp, long c) [Built-in Function]

註解為:
You may use __builtin_expect to provide the compiler with branch prediction information. In general, you should prefer to use actual profile feedback for this (‘-fprofile-arcs’), as programmers are notoriously bad at predicting how their programs actually perform. However, there are applications in which this data is hard to collect.The return value is the value of exp, which should be an integral expression. The semantics of the built-in are that it is expected that exp == c.


它的意思是:我們可以使用這個函式人為告訴編繹器一些分支預測資訊“exp==c” 是“很可能發生的”。

#define likely(x) __builtin_expect(!!(x), 1)也就是說明x==1是“經常發生的”或是“很可能發生的”。
使用likely ,執行if後面語句的可能性大些,編譯器將if{}是的內容編譯到前面, 使用unlikely ,執行else後面語句的可能性大些,編譯器將else{}裡的內容編譯到前面。這樣有利於cpu預取,提高預取指令的正確率,因而可提高效率。

舉個例子(核心版本2.6.22.6):/kernel/shed.c中有一段:
if (likely(!active_balance)) {

/* We were unbalanced, so reset the balancing interval */
sd->balance_interval = sd->min_interval;
} else {
/*
* If we've begun active balancing, start to back off. This
* case may not be covered by the all_pinned logic if there
* is only 1 task on the busy runqueue (because we don't call
* move_tasks).
*/
if (sd->balance_interval max_interval)
sd->balance_interval *= 2;
}

編譯過程中,會將if後面{}裡的內容編譯到前面,else 後面{}裡的內容編譯到後面。若將likely換成unlikely 則正好相反。

總之,likely與unlikely互換或不用都不會影響程式的正確性。但可能會影響程式的效率。

if(likely(foo))  //認為foo通常為1

if(unlikely(foo)) //認為foo通常為0


感謝各位光顧!
不知道有沒有寫清楚,望指正!
疑惑:
為什麼likely或是unlikely要定義成__builtin_expect(!!(x), 1),而不直接用__builtin_expect(x, 1)?" !!(x) "與" x "有什麼不同?

另外核心2.6.31.5中likely和unlikely還有一種定義:
# 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

相關推薦

linux likelyunlikely

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

Linux 內核 likely unlikely 的宏定義解析

帶來 內核版本 sta don 等價 ddc 編譯 views lines 在 2.6 內核中,隨處能夠見到 likely() 和 unlikely() 的身影,那麽為什麽要用它們?它們之間有什麽差別? 首先要明白: if(likel

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 核心中 likely unlikely 的巨集定義解析

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

(轉載)核心likely() unlikely()

00000000 <testfun>:    0:   55                      push   %ebp    1:   89 e5                   mov    %esp,%ebp    3:   8b 45 08                mov 

學習筆記 --- LINUX核心裡面的likelyunlikely

看核心時總遇到if(likely( )){}或是if(unlikely( ))這樣的語句,最初不解其意,現在有所瞭解,所以也想介紹一下。 likely() 與 unlikely()是核心(我看的是2.6.22.6版本,2.6的版本應該都有)中定義的兩個巨集。位於/in

Linux 用戶的管理

表示 方式 打開 消息接收 users 模式 blog 方法 接收 在linux中建立組的指令是 groupadd 組名 相應的,刪除組的指令: groupdel 組名 查看自己用戶的組: groups 用戶管理: useradd -s/bin/bash -g 組名 用

linuxdudf的區別和聯系

roc 換行 -h lib 文件占用 use .html -m 詳細 1,兩者區別 du,disk usage,是通過搜索文件來計算每個文件的大小然後累加,du能看到的文件只是一些當前存在 的,沒有被刪除的。他計算的大小就是當前他認為存在的所有文件大小的累加和。 df

Linux rpmyum的區別

rpm1.rpm :RedHat package manage的簡寫rpm 是linux的一種軟件包名稱,以.rmp結尾,安裝的時候語法為:rpm -ivh,rpm包的安裝有一個很大的缺點就是文件的關聯性太大,有時候裝一個軟件要安裝很多其他的軟件包,很麻煩,2.yum(全稱為 Yellow dog Upda

LinuxSambaNFS的共享示例

Linux中Samba與NFS的共享示例在這裏面所有的服務器為CentOS 6.9,samba客戶端和NFS客戶端均為CentOS 7.2要完成以下操作需要安裝的軟件包:yum install httpd mariadb-server(CentOS6.9是mysql-server)nfs-utils sam

linuxchmodchown兩個命令詳解

In 第一個 ID 利用 root chown 資料 後綴 沒有 在linux系統中chmod,chown命令都可以來設置權限了,但它們也是有區別的,下文小編為各位介紹chmod與chown兩個命令用法與區別介紹。 今天要分享的2個命令也是我們平時常用的,chmod與cho

likely()unlikely()函式的作用

#define likely(x)  __builtin_expect(!!(x), 1) 也就是說明x==1是“經常發生的”或是“很可能發生的”。 所以使用likely ,執行if後面語句的可能性大些,編譯器將if{}是的內容編譯到前面 使用unlikely ,執行else後

linuxchmodchown

前言 今天要分享的2個命令也是我們平時常用的,chmod與chown看似拼寫還有點差不多,但是兩者的用途是不同的。chmod是用來設定資料夾和檔案許可權的,比如我們在VPS主機中檔案不可讀寫,需要用來設定777許可權;而chown是用來設定使用者組的,比如授權某使用者組,方便控制使用者許可權。

linuxdudf的區別和聯絡

1,兩者區別  du,disk usage,是通過搜尋檔案來計算每個檔案的大小,然後累加,du能看到的檔案只是一些當前存在的,沒有被刪除的。他計算的大小就是,當前他認為存在的所有檔案大小的累加和。 df,disk free,通過檔案系統來快速獲取空間大小的資訊。當我們刪除

Linuxdfdu的區別

1,兩者區別  du,disk usage,是通過搜尋檔案來計算每個檔案的大小然後累加,du能看到的檔案只是一些當前存在  的,沒有被刪除的。他計算的大小就是當前他認為存在的所有檔案大小的累加和。 df,disk free,通過檔案系統來快速獲取空間大小的資訊,當我們刪除一個

Linuxaptapt-get命令的區別解釋

Ubuntu 16.04 釋出時,一個引人注目的新特性便是 apt 命令的引入。其實早在 2014 年,apt 命令就已經發布了第一個穩定版,只是直到 2016 年的 Ubuntu 16.04 系統釋出時才開始引人關注。 隨著 apt install package 命令的

LinuxCPU記憶體效能監測

在系統維護的過程中,隨時可能有需要檢視 CPU 使用率記憶體使用情況的需要,尤其是涉及到JVM,程式調優的情況,並根據相應資訊分析系統狀況的需要。 top命令 top命令是Linux下常用的效能分析工

LINUXprintfecho的區別

(1)首先echo是回顯,即代表回車顯示,是自帶換行的;而printf只是打印出來,沒有換行 (2)echo只是回顯沒有變數替換功能;printf是有的 舉例:假如我們定義好變數a='hello world' 則 echo "%s" $a  顯示的結果就是%s 而 prin

linuxplatform中斷

學習總結: 在linux2.6中引入platform的概念,包括platform_device與platform_driver結構。每個裝置的資源(地址、中斷號等)在platform_device中的resource中描述,resource結構在kernel/include

linuxcpmcopy異同

同:都是複製功能。 異: 1、mcopy是mtools指令,可以在DOS系統中複製檔案或者在DOS與Linux作業系統之間進行檔案複製。 2、cp命令用於linux系統複製檔案或目錄。   ______________________________________