1.記憶體對齊是什么?
對結構體和類來說,讓變數不是緊挨著存放,而是通過變數位元組倍數的形式存放
2.為什么會有記憶體對齊?
- 增加cpu的訪問資料的速度
- 對于cpu來說,資料從記憶體中讀到快取中去,是通過偏移量(offset)進行讀取,也就是常說的通過塊來讀取,而不是按照位元組讀取,
- 讀取非記憶體對齊的資料,會出現一次必須讀取offset和offset+1兩塊資料這種情況,這需要為芯片增加額外的加法器( 為了得到offset+1 ),為了上述這種可能,而增加額外的設備,并且每一次的增加訪問時間,顯然是不明智的
- 還有一點就是讀了兩次,讀到快取的位置上也需要兩次,同樣降低效率
- 方便于不同機器、不同平臺進行資料的準確讀取
3.記憶體對齊規則
-
規則1:需要按照min(pack,sizeof(變數本身))的倍數進行選擇開始位置
-
規則2:整體按照min(pack,sizeof(位元組數最大的變數))的倍數進行計算
-
規則3:陣列則按照本身是哪種型別變數進行計算,同樣遵循規則1
-
規則4:結構體中的結構體X,X內部遵循規則1計算大小,并且選擇位置也遵循規則1
-
注意:
- 規則1和2,為主要原則,3和4作為拓展
- sizeof得到所占位元組數,pack為對齊模數
- 查看對齊模數#pragma pack(show),編譯時會顯示
4.案例
運行環境:Microsoft Visual Studio Community 2022 (64 位) - Current版本 17.3.4
對齊模數:#pragma pack(show) == 16 
- 案例1
pack == 16
struct A{
char a; //0-3
int b; //4-7
double c;//8-15
}; // 16/8 可除
規則1:需要按照min(pack,sizeof(變數本身))的倍數進行選擇開始位置
規則2:整體按照min(pack,sizeof(位元組數最大的變數))的倍數進行計算
pack == 2
struct B{
char a; //0-2
int b; //2-5
double c;//6-13
}; // 14/2 可除
規則1:需要按照min(pack,sizeof(變數本身))的倍數進行選擇開始位置
規則2:整體按照min(pack,sizeof(位元組數最大的變數))的倍數進行計算
- 案例3
pack == 16
struct C{
char a; //0-1
short b[3];//2-7 --->the place
int c; //8-15
double d;//16-23
}; // 24/8 可除
規則3:陣列則按照本身是哪種型別變數進行計算,同樣遵循規則
- 案例4
pack == 16
struct D{
char a; //0-7
struct C b;//8-31
int c; //32-39
double d;//40-47
}; // 48/8 可除
規則4:結構體中的結構體X,X內部遵循規則1計算大小,并且選擇位置也遵循規則1
pack == 2
struct D{
char a; //0-1
struct B b;//2-15
int c; //16-19
double d;//20-7
}; // 28/2 可除
規則4:結構體中的結構體X,X內部遵循規則1計算大小,并且選擇位置也遵循規則1
5.其他的注意
-
空類和空結構體的sizeof大小為1
-
該環境下指標的大小為8個位元組
6.類與記憶體對齊
待補充鏈接
參考
參考資料:淺談CPU記憶體訪問要求對齊的原因 – 仰望蒼天思寰宇 (yangwang.hk)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/544271.html
標籤:其他
