close
雖然不是內核工程師,但是也經常使用這兩個宏,不過一直沒有深究。剛才看了Bean_lee評論了一篇關於likely()和unlikely()的文章,於是也過去湊了個熱鬧。

該文章前面沒有什麽問題,我也不再重復,但是最後有個錯誤。“另外有一點要註意的是,由於likely定義時用的常量是1,unlikely用的常量是0,這正好符合c/c++語言中bool變量的實際值,而_builtin_expect()函數對exp與c進行嚴格相等的比較的,
因此使用likely和unlikely時,其參數應該只使用邏輯表達式,因為邏輯表達式的值只有0或1。除非真要判斷某個變量的值是1或0時,才會將其它類型的參數傳給likely或unlikely。這一點可能很多人會不小心用錯。”,引自:http://blog.chinaunix.net/space.php?uid=24708340&d...

我看到這段文字時,嚇了一跳。我使用likely和unlikely時從來沒註意過參數非得是邏輯表達式的值啊,即0和1。難道都用錯了。。。想了一下,就知道該博主想錯了。

當使用likely和unlikely的時候,參數可以為任何表達式。不是邏輯表達式沒有關系,絕不會有錯。我來解釋一下:
#define likely(x) __builtin_expect(!!(x),1)
#define unlikely(x) __builtin_expect(!!(x),0)
這是likely和unlikely的定義。看一眼定義,!!(x)這個用法就會讓人覺得奇怪,為什麽要!!呢?否定的否定,不就是肯定嗎?幹嘛多此一舉呢?這就是一個技巧,學習kernel的時候,可以學到不少類似的技巧。

按照__builtin_expect的定義,要用第一個參數和第二個參數比較,它期望的值是true。第二個值是1。這裏的!!(x)就是為了保證當x本身作為邏輯值為true的時候,其!!(x)值為1。舉個簡單的例子:
if (likely(5)) {
    printf("Hit!\n");
}
else {
    printf("Not hit\n");
}
本身if (5)為true,因為C標準裏面規定任何非0的值均為true。Ok,!(5)為0,而!!(5)為1。這就是為啥likely和unlikely要使用!!(x),就為了其邏輯判斷的值為1或者0。
arrow
arrow
    全站熱搜

    主要步驟 發表在 痞客邦 留言(0) 人氣()