- 對齊概述
- 對齊的規則
- 計算步驟
- 對比
- 小結
對齊概述
1.性能原因:為了提高cup的效率通路記憶體的速度,若是通路未對齊的記憶體,處理器需要作兩次通路;而通路對齊的記憶體,則隻需要一次通路。
2.編譯器相關:有的編譯器已經優化了記憶體對齊,是以記憶體對齊依賴于編譯器。
對齊的規則
參考 結構體對齊問題
說實話,規則看起來不太好了解,直接模仿下面步驟即可
計算步驟
以32位機器為例,工具為vs2008
類型 | 所占位元組 |
---|---|
char | 1 |
bool | 1 |
short | 2 |
int | 4 |
long | 4 |
float | 4 |
double | 8 |
指針 | 4 |
示例
struct person
{
char a;
double b;
int c;
int d;
char e;
double f;
char g;
};
步驟:
1.找出person中位元組數最長的成員b和f,長度為 n = 8;
2.從第一個成員 a 開始計算,将 a 擺在 p = 0x00000 的位置。
3.計算第二個成員 b ,此時 b 的長度為 l = 8 ,其擺放的起始位址 p 需要滿足 p % l = 0 的條件。是以需要在之前填充7個位元組,則 p = 0x00008,其填充0x00008 - 0x00015共八個位元組。
4.計算第三個成員 c ,c 的長度為 l = 4 , 其擺放的起始位址 p = 0x00016, 滿足 p % l = 0,是以不需要在之前填充位元組,其填充0x00016 - 0x00019共四個位元組。
5.下面依次類推。
6.最後計算g,填充一個位元組0x00040。
7.0x00000 - 0x00040共 41 個位元組,總位元組數sum必須滿足 sum % n = 0; n 數值看步驟1,是以最後還需要填充7個位元組,則 sum = 48;
表格示例:
成員 | 類型 | 所占位元組 | 填充位元組數 | 存儲位址 |
---|---|---|---|---|
a | char | 8 | 0x00000 | |
b | double | 1 | 7 | 0x00008 - 0x00015 |
c | int | 4 | 0x00016 - 0x00019 | |
d | int | 4 | 0x00020 - 0x00023 | |
e | char | 1 | 0x00024 | |
f | double | 8 | 7 | 0x00032 - 0x00039 |
g | char | 1 | 0x00040 |
長度sum = 41,成員變量最長類型所占位元組數 n = 8,為滿足 sum % n = 0,需填充7個位元組,sum = 48;
對比
順序1
struct person2
{
double b;
char a;
int c;
int d;
char e;
double f;
char g;
};
将 a 和 b 的順序調換,算出來的長度為 40,
順序2
struct person3
{
double b;
double f;
int c;
int d;
char e;
char a;
char g;
};
此時的長度為 32.
小結
由于排列順序不一樣,person3 所占的空間隻有person的 67%,若是使用person結構體存儲資料量有一個GB,那麼使用person3來存儲,隻需要686MB,是以可以從記憶體對齊的角度來優化代碼,節省空間。
此段示例屬于最簡單的那種,還有更複雜的包含數組的,還待研究。。。