記憶體對齊演算法
阿新 • • 發佈:2021-12-06
什麼是向上對齊?向上對齊是指根據某些硬體平臺或函式的要求,對要處理的資料大小需要保證一定的規則。常見的是記憶體對齊,比如要保證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,收穫多多喲!!!
有時候,不小心知道了一些事,才發現自己所在乎的事是那麼可笑。