怎樣快速判斷掩碼第乙個為1的Bit位置

2021-08-03 17:08:24 字數 1196 閱讀 3098

在底層軟體開發過程中經常使用位掩碼標識乙個狀態符號。舉乙個例子來說,比如乙個u32型別的變數use_mask用來表示32個記憶體塊的占用狀態,變數的每一位代表乙個記憶體塊的使用狀態,1b表示空閒,0b表示被占用。當應用程式需要使用乙個空閒塊時,只需要查詢use_mask哪一位為1,就可以直接將給bit位對應的記憶體塊拿來使用了,當然在使用前將該位置1了。同理,使用完給記憶體塊後,也需要將對應位置0就可以了。

那麼,如何根據use_mask得到為1位的位置呢,比較直接的方法如下:

int getunusemem(u32 usemask)

return -1;

}顯然,用這種方法可以得到期望的結果,但是該函式的計算量是與輸入引數的內容相關的,最壞情況的運算時間可能是最好情況的32倍。這在一些實時要求比較高的系統中是很難接受的。同時,在函式**中存在迴圈,判斷分支,也非常不適合當前具有預取指令,亂序執行等功能的處理器提高其效能。當然,我們可以將迴圈展開,定義暫存器變數等技巧來解決一部分問題,但是是否有其它方法嗎。這裡考慮了兩種方案,拋磚引玉:

該方法一般在掩碼長度為8位時比較常見,即定義乙個陣列x,陣列長度為2 的n次方,n為掩碼的長度。如掩碼為8位時可定義乙個256個單元的陣列,陣列第m個單元初始化為但掩碼值為m時其第乙個為1位的位置,比如m=0xf4,則11110100b,其第乙個為一的位在bit2上,則x[m]=2,同理但x[0xf5]=0,當然x[0x00]=-1。有了這張表,那麼查詢位元1位置的函式實現很簡單:

int x[256]=

int getunusemem(u8 usemask)

那麼問題是當

usemask為32位時怎麼辦,難道構建2的32次方長度的陣列嗎,也即4g個單元,當然不好,除非你要想搞死你的機器。那就分段處理吧。

int getunusemem(u32 usemask)

如果是64位的掩碼呢,最多要判斷8次,顯然不合適,因此可以使用兩級解碼,第一級掩碼中一位代表下一級掩碼的相應8位是否有1。

int x[256]=

u8 y[256]=

int getunusemem(u8 usemask1,

u64 usemask)

使用位運算可以更快的得到,也不需要用查詢表占用記憶體空間,由於訪問記憶體非常影響處理器的效率,而使用這種方式會使用暫存器或者cpu快取,不通過北橋再經過ddrii記憶體控制器得到,因此效率比查詢表要高。

int getunusemem(

u32 usemask)

1 第乙個網頁

emmet外掛程式 自動生成html 片段 tab鍵 在html中,注釋如下書寫 其他叫法 標籤 標記 href b站a 整體 element 元素 元素 起始標記 begin tag 結束標記 end tag 元素內容 元素屬性 注 起始標記與結束標記相同,且結束標記只比起始標記多乙個 起始標記名...

第乙個遊戲 啟程 1

通過從0寫這個專案,掌握遊戲開發所說要的c c 的高階特性,快速強化c c 掌握遊戲開發的基本概念 基本流程,快速入門遊戲開發。玩遊戲是快樂的,開發遊戲同樣是快樂的,甚至更快樂,享受 造物主 的樂趣。蘋果wwdc大會上,一位82歲的日本老奶奶若宮正子,是一名銀行退休職員,成了全場最年長開發者。蘋果公...

(二)1 第乙個webapi

2 要選擇.net core 我記得 準備工作就做到這了,下面就是正式開始了!開始當然是新建乙個專案,請記住,我是用的webapi,之前也要有相關mvc基礎才行。選擇 net core 選擇 asp.net core web應用程式 填寫專案名稱 選擇專案存放的目錄 誰要放c盤,就別跟我玩了 確認 ...