為什麼要進行記憶體對齊以及對齊規則

2021-08-09 20:24:24 字數 1713 閱讀 1277

#includeusing namespace std;

struct a;

struct b;

int main(){

cout《以上結構體變數數量型別相同。但是sizeof卻不同,

sizeof(a) is 12

sizeof(b) is  8

那麼問題來了,為什麼兩個一樣的結構體,但是sizeof大小卻不同?

答案就是記憶體對齊導致結果不同

對於大多數程式設計師來說,記憶體對齊是透明的,這是編譯器該幹的活,編譯器為程式中的每個資料單元安排在合適的位置上,從而導致了不同的宣告順序的結構體大小不同。

那麼編譯器為什麼要進行記憶體對齊呢?本來sizeof(int +char +short)應該是7,對齊之後反而變大了,為什麼?

先來看看記憶體對齊的規則?

1.對於結構的各個成員,第乙個成員位於偏移為0的位置,以後的每個資料成員的偏移量必須是  min(#pragma pack()指定的數,這個資料成員的自身長度)的倍數

2.在所有的資料成員完成各自對齊之後,結構或聯合體本身也要進行對齊,對齊將按照 #pragram pack 指定的數值和結構或者聯合體最大資料成員長度中比較小的那個  也就是  min(#pragram pack() , 長度最長的資料成員);

#pragram pack(n)  表示的是設定n位元組對齊,vc6預設的是8

接下來以第乙個結構體為例說明上述規則?

a:char佔乙個位元組,起始偏移為零,int 佔四個位元組,min(8,4)=4;所以應該偏移量為4,所以應該在char後面加上三個位元組,不存放任何東西,short 佔兩個位元組,min(8,2)=2;所以偏移量是2的倍數,而short偏移量是8,是2的倍數,所以無需新增任何位元組,所以第乙個規則對齊之後記憶體狀態為  0***|0000|00    

此時一共佔了10個位元組,但是還有結構體本身的對齊, min(8,4)=4;所以總體應該是4的倍數,所以還需要新增兩個位元組在最後面,所以記憶體儲存狀態變為了 0***|0000|00xx   一共佔據了12個位元組

接下來我們好好討論一下記憶體對齊的作用?

1.平台原因(移植原因):不是所有的硬體平台都能訪問任意位址上的任意資料,某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常

2.硬體原因:經過記憶體對齊之後,cpu的記憶體訪問速度大大提公升。具體原因接下來解釋

圖一:我們普通程式設計師心中的記憶體印象,由乙個個位元組組成,但是cpu卻不是這麼看待的

圖二:cpu把記憶體當成是一塊一塊的,塊的大小可以是2,4,8,16 個位元組,因此cpu在讀取記憶體的時候是一塊一塊進行讀取的,塊的大小稱為(memory granularity)記憶體讀取粒度。

我們再來看看為什麼記憶體不對齊會影響讀取速度?

假設cpu要讀取乙個4位元組大小的資料到暫存器中(假設記憶體讀取粒度是4),分兩種情況討論:

1.資料從0位元組開始

2.資料從1位元組開始

解析:當資料從0位元組開始的時候,直接將0-3四個位元組完全讀取到暫存器,結算完成了。

當資料從1位元組開始的時候,問題很複雜,首先先將前4個位元組讀到暫存器,並再次讀取4-7位元組的資料進暫存器,接著把0位元組,4,6,7位元組的資料剔除,最後合併1,2,3,4位元組的資料進暫存器,對乙個記憶體未對齊的暫存器進行了這麼多額外操作,大大降低了cpu的效能。

但是這還屬於樂觀情況,上文提到記憶體對齊的作用之一是平台的移植原因,因為只有部分cpu肯幹,其他部分cpu遇到未對齊邊界就直接罷工了。

參考:

為什麼要進行記憶體對齊以及對齊規則

什麼是記憶體對齊?為什麼要記憶體對齊?

要了解為什麼要記憶體對齊,首先我們要了解什麼是記憶體對齊 typedef struct a typedef struct b 分別對他們求大小,sizeof a sizeof b 我們所得到的結果是不同的,sizeof a 24而sizeof b 16為什麼會產生不一樣的結果呢?這是非常簡單的乙個例...

為什麼要記憶體對齊

當我們聽到 記憶體對齊 這個概念時,從字面意思來看,很容易理解。那就是讓記憶體按一定規則對齊。當然 就會有人說 你這不是廢話 現在我就來說一說為什麼要記憶體對齊以及怎麼個對齊法 如何對齊 記憶體對齊 記憶體對齊 應該是 編譯器的 管轄範圍 編譯器為程式中的每個 資料單元 對於記憶體對齊問題,主要存在...

為什麼要記憶體對齊?

cpu訪問非對齊的記憶體時為何需要多次讀取再拼接?首先簡單說一下何為記憶體對齊。例如,當cpu需要取4個連續的位元組時,若記憶體起始位置的位址可以被4整除,那麼我們稱其對齊訪問。反之,則為未對齊訪問。比如從位址0xf1取4位元組就是非對齊 位址 訪問。簡單的看來,對於乙個資料匯流排寬度為32位的cp...