我也說說宏定義likely()和unlikely()

作者:gfree.wind@gmail.com
博客:blog.focus-linux.net ? linuxfocus.blog.chinaunix.net
?
?
本文的copyleft歸gfree.wind@gmail.com所有,使用GPL發布,可以自由拷貝,轉載。但轉載請保持文檔的完整性,注明原作者及原鏈接,嚴禁用于任何商業用途。
======================================================================================================
雖然不是內核工程師,但是也經常使用這兩個宏,不過一直沒有深究。剛才看了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&do=blog&id=3047035

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

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

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

關于為什么likely和unlikely可以提高程序的performance,我就不獻丑了。給個官方的文獻鏈接:http://kernelnewbies.org/FAQ/LikelyUnlikely

總的來說,它們是對編譯器的一種指示,告訴編譯器哪個分支更有可能發生,來最大的滿足CPU的流水線作業。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/278338.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/278338.shtml
英文地址,請注明出處:http://en.pswp.cn/news/278338.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

圖片懶加載與預加載

預加載 常用的是new Image();,設置其src來實現預載,再使用onload方法回調預載完成事件。function loadImage(url, callback) {var img new Image(); //創建一個Image對象,實現圖片的預下載img.src url;if (img.complete){ // 如果圖片已經存…

電腦pin重置_如果忘記了如何重置Windows PIN

電腦pin重置A good password or PIN is difficult to crack but can be difficult to remember. If you forgot or lost your Windows login PIN, you won’t be able to retrieve it, but you can change it. Here’s how. 好的密碼或PIN很難破解,但很難記住。 如果…

android.support不統一的問題

今天supprt28遇到的問題,由于28還是預覽版,還存在一些bug 都是因為如果程序內出現不同的,support或者其他外部引用庫的多個版本,Gradle在進行合并的時候會使用本地持有的,最高版本的來進行編譯,所以25的sup…

輕松查看Internet Explorer緩存文件

Sometimes you may need a quick and easy way to access Internet Explorer’s cache. Today we take a look at IECacheView which is a great application to get the job done. 有時,您可能需要一種快速簡便的方法來訪問Internet Explorer的緩存。 今天&#xf…

洛谷P1019 單詞接龍

題目描述 單詞接龍是一個與我們經常玩的成語接龍相類似的游戲,現在我們已知一組單詞,且給定一個開頭的字母,要求出以這個字母開頭的最長的“龍”(每個單詞都最多在“龍”中出現兩次),在兩個單詞相連時&…

【Java】接口(interface)VS抽象類

接口(interface)可以說成是抽象類的一種特例,接口中的所有方法都必須是抽象的。接口中的方法定義默認為public abstract類型,接口中的成員變量類型默認為public static final。另外,接口和抽象類在方法上有區別&#x…

latex插入gif_如何將照片和GIF插入Google幻燈片

latex插入gifUsing text (and only text) in your Google Slides presentation is a great way to lose the attention of your audience. Inserting photos and animated GIFs can immediately spice things up by emphasizing the important points you make. 在Google幻燈片…

子矩陣

題目描述 給出如下定義: 子矩陣:從一個矩陣當中選取某些行和某些列交叉位置所組成的新矩陣(保持行與列的相對順序)被稱為原矩陣的一個子矩陣。例如,下面左圖中選取第2、4行和第2、4、5列交叉位置的元素得到一個2*3的子…

springboot入門(一)--快速搭建一個springboot框架

原文出處 前言在開始之前先簡單介紹一下springboot,springboot作為一個微框架,它本身并不提供Spring框架的核心特性以及擴展功能,只是用于快速、敏捷地開發新一代基于Spring框架的應用程序,總的來說springboot不是為了要替代Sprin…

q-dir 打不開文件_Q-Dir –多窗格文件管理器

q-dir 打不開文件Sometimes when looking through a file manager, it would be nice to have more than a dual-pane view. Now you can manage your files with up to four viewing panes at once with Q-Dir. 有時,在查看文件管理器時,擁有多個雙窗格…

用面向對象的方法寫敲門磚

一道名為"敲門磚"的面試題: 用面向對象的方法寫,點擊列表內,子元素的子標簽, 來刪除子元素 敲門磚考點: 遞歸(刪除標簽, 需要找到列表的直屬子標簽, 需要通過遞歸層層往上找, parentNode)冒泡(只需為頂級父元素addEventListener綁定事件, 并通過e.target區分子標簽, …

windows10加載動畫_如何關閉動畫并使Windows 10看起來更快

windows10加載動畫Windows 10 fades and window animations are pure eye candy, but waiting for them to load can make your PC seem a bit slow. If you’d like an instant response, you can disable Windows 10’s animations for a snappier desktop experience. Windo…

JData大數據競賽18年賽題-如期而至-用戶購買時間預測

年前做的,也是學習別人的作品作為記錄 一、賽題 表1:sku基本信息表(jdata_sku_basic_info) 表2:用戶基本信息表(jdata_user_basic_info) 表3:用戶行為表(jdata_user_acti…

LNMP架構(二)

2019獨角獸企業重金招聘Python工程師標準>>> 一 Nginx安裝 1、切換目錄 # cd /usr/local/src 2、下載 # wget http://nginx.org/download/nginx-1.12.1.tar.gz 3、解壓 # tar xzvf nginx-1.12.1.tar.gz 4、切換到nginx目錄下 # cd nginx-1.12.1/ 5、編譯 # ./confi…

edge無法上網dns_如何在Microsoft Edge中通過HTTPS啟用DNS

edge無法上網dnsMicrosoft will one day enable DNS over HTTPS (DoH) for all Windows applications, but you can enable it in the new version of Microsoft Edge today with a hidden flag. DoH will improve your security and privacy online, but it isn’t yet enable…

UIButton小結

前言 本來沒有打算寫這篇文章的, 主要是因為在工作中遇到一些同事再用 有UIButton的時候, 有些很基本的,系統API提供的都不知道, 例如 如何讓UIButton的文字居上,居左, 居右, 居下對其等一些基本點, 為此我特地寫了一下UIButton小結 UIButton回顧 繼承關系 NSObject -> UIRe…

Channel Allocation HDU1373

染色問題&#xff1a;相鄰不能染同一種顏色 最少需要的顏色的數量最大團點的數量 #include<bits/stdc.h> using namespace std;#define N 27int n; int mp[N][N]; int ans; int alt[N][N]; int Max[N];bool dfs(int cur,int tot)//cur是s1集合的個數 {if(0cur){if(tot>…

satis原理淺析

什么是satis 我們一般是從packagist獲取composer包的&#xff0c;但這些都是公開的。那如果我們想創建自己的私有庫呢&#xff0c;比如企業就會有這方便的需要&#xff0c;那我們就可以用satis來創建自己的私有庫。 Satis 是一個靜態的 composer 資源庫生成器。它像是一個超輕量…

HDU - 5686-Problem B (遞推+高精)

度熊面前有一個全是由1構成的字符串&#xff0c;被稱為全1序列。你可以合并任意相鄰的兩個1&#xff0c;從而形成一個新的序列。對于給定的一個全1序列&#xff0c;請計算根據以上方法&#xff0c;可以構成多少種不同的序列。 Input 這里包括多組測試數據&#xff0c;每組測試數…

c#寫字板實現加粗功能_Windows 7中寫字板和繪畫中的新功能

c#寫字板實現加粗功能WordPad and Paint are often overlooked accessories included in all versions of Windows since 95. They are still included in Windows 7 and now have a new look with some enhanced features. Here we will take a look at some of the new impro…