自然對齊規則

2021-08-29 02:52:10 字數 1406 閱讀 4177

基本型別的長度計算:

sizeof(char)的長度為:1

sizeof(short)的長度為:2

sizeof(int)的長度為:4

sizeof(long)的長度為:4(win x86和x64都為4,linux x86為4,x64為8)

sizeof(float)的長度為:4

sizeof(double)的長度為:8

sizeof(bool)的長度為:1(c++裡)

sizeof(bool)的長度為:4(windows平台)

sizeof(p)的長度:x86為4,x64為8,其中p為指標型別變數,如char *p,也就是說,在x86平台,指標的長度是4,在x64平台,指標的長度是8。 

結構體長度的計算:

自然對齊應該遵守如下兩條規則:

1)資料成員對齊規則:

在預設情況下,各成員變數存放的起始位址相對於結構的起始位址的偏移量:sizeof(型別)或其倍數

2)整體對齊規則:

結構的總大小也有個約束條件:最大sizeof(型別)的整數倍

棧上對齊方式:

與結構體的自然對齊不同。

1.在x86平台,棧上對齊方式是整數相關型別按照4位元組對齊,浮點數按照8位元組對齊;

2.在x64平台,棧上浮點數按照16位元組對齊。

記憶體對齊的主要作用是:

2、  效能原因:經過記憶體對齊後,cpu的記憶體訪問速度大大提公升。

詳細原因稍後解釋。

圖一:這是普通程式猿心目中的記憶體印象。由乙個個的位元組組成。而cpu並非這麼看待的。

圖二:cpu把記憶體當成是一塊一塊的,塊的大小能夠是2,4。8。16位元組大小。因此cpu在讀取記憶體時是一塊一塊進行讀取的。塊大小成為memory access granularity(粒度) 本人把它翻譯為「記憶體讀取粒度」 。

如果cpu要讀取乙個int型4位元組大小的資料到暫存器中,分兩種情況討論:

1、資料從0位元組開始

2、資料從1位元組開始

再次如果記憶體讀取粒度為4。

圖三:當該資料是從0位元組開始時,非常cpu僅僅需讀取記憶體一次就可以把這4位元組的資料全然讀取到暫存器中。

當該資料是從1位元組開始時,問題變的有些複雜。此時該int型資料不是位於記憶體讀取邊界上。這就是一類記憶體未對齊的資料。

圖四:此時cpu先訪問一次記憶體。讀取0—3位元組的資料進暫存器。並再次讀取4—5位元組的資料進暫存器,接著把0位元組和5,6,7位元組的資料剔除。最後合併1,2,3。4位元組的資料進暫存器。對乙個記憶體未對齊的資料進行了這麼多額外的操作。大大減少了cpu效能。

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

記憶體對齊(自然對齊)

參考 今天與超,暉,棟,宇幾人論此問題,終得以下結論,不知正確與否,姑且記下。對於32位機,cpu的記憶體讀寫週期是4word,所以在記憶體對齊時,皆以此填滿。如 struct a char a double b char c sizeof a 4 8 4 16 struct b char a do...

自然對齊和強制對齊

一 自然對齊 各個型別自然對齊,即其起始記憶體位址必須是其型別本身的整數倍。對於結構體來說,結構體的起始記憶體位址,必須是結構體中成員最大長度型別的整數倍。結構體自然對齊應遵守如下規則 1 資料成員對齊規則 應該是sizeof 成員變數型別 或者sizeof 成員變數型別 的倍數。應該是子結構體中最...

struct自然對齊和指定對齊

intel 微軟等公司曾經出過一道類似的面試題 include pragma pack 8 struct example1 struct example2 pragma pack int main int argc,char argv 答案是 816 4解釋 程式中第2行 pragma pack 8...