1. 程式人生 > 其它 >記憶體對齊演算法

記憶體對齊演算法

什麼是向上對齊?向上對齊是指根據某些硬體平臺或函式的要求,對要處理的資料大小需要保證一定的規則。常見的是記憶體對齊,比如要保證4位元組的記憶體對齊,程式碼如下(注意其中的符號——&):

 #define MEM_ALIGN_SIZE(size)    (((size) + 3) & (~3))

通常情況下,對齊的大小為2的整數次冪,4,8,16... 這種大小的對齊方式這樣寫:

 #define ALIGN_SIZE  4
 #define UPPER_ALIGN(size)   (((size) + ALIGN_SIZE - 1) & (~(ALIGN_SIZE - 1)))

比如,某一款儲存晶片只能以512位元組的方式進行讀寫,但是為了保證程式的相容性(有些晶片支援隨機讀寫),讀寫資料時我不能固定的以512位元組進行讀寫,我會增加一個抽象層,對應用層遮蔽儲存晶片的不同。如下圖所示:

抽象層中肯定是隨機讀寫函式,但是到了操作具體的儲存晶片時就需要保證512位元組的對齊了。虛擬碼如下:

 /*晶片讀取函式*/
 #define ALIGN_SIZE  512
 #define UPPER_ALIGN(size)   (((size) + ALIGN_SIZE - 1) & (~(ALIGN_SIZE - 1)))
 int32_t chip_content_read(chip_id, content_buf, read_size)
 {
     //upper align
     read_size = UPPER_ALIGN(read_size);
     ...
 }

注意:

只有要對齊的數字是2的整數次冪的時候,才能使用取地址符號——&。如果數字不是2的整數次冪,那麼就該這樣寫:

 #define ALIGN_SIZE  9
 #define UPPER_ALIGN(size) ((((size) + ALIGN_SIZE - 1) / (ALIGN_SIZE)) * (ALIGN_SIZE))) 

其實,以2的整數次冪進行對齊時,也可以寫成上面這種形式,只不過因為對齊的數字是2的整數次冪,有些特殊,故可以使用取地址符&(請大家自行證明下,程式碼看千遍,不如動手敲一遍)。

Tips

對2的整數次冪的資料進行商和取餘,有兩個小技巧。假設m為2的整數次冪。

求商——n/m:

n / m = n >> log2(m)

求餘——n%m:

n % m = n & (m - 1)

牆裂建議大家看下linux核心中的log2.h,收穫多多喲!!!

有時候,不小心知道了一些事,才發現自己所在乎的事是那麼可笑。