理論上計算機對于任何變量的訪問都可以從任意位置開始,然而實際上系統(tǒng)會對這些變量的存放地址有限制,通常將變量首地址設(shè)為某個數(shù)N的倍數(shù),這就是內(nèi)存對齊。
為什么要內(nèi)存對齊?
1. 硬件平臺限制,內(nèi)存以字節(jié)為單位,不同硬件平臺不一定支持任何內(nèi)存地址的存取,一般可能以雙字節(jié)、4字節(jié)等為單位存取內(nèi)存,為了保證處理器正確存取數(shù)據(jù),需要進行內(nèi)存對齊。
- 提高CPU內(nèi)存訪問速度,一般處理器的內(nèi)存存取粒度都是N的整數(shù)倍,假如訪問N大小的數(shù)據(jù),沒有進行內(nèi)存對齊,有可能就需要兩次訪問才可以讀取出數(shù)據(jù),而進行內(nèi)存對齊可以一次性把數(shù)據(jù)全部讀取出來,提高效率。
內(nèi)存對齊規(guī)則
1. 數(shù)據(jù)成員對齊規(guī)則:struct或者union的數(shù)據(jù)成員,第一個數(shù)據(jù)成員放在offset為0的地方,以后每個數(shù)據(jù)成員都按照#pragma pack數(shù)值和這個數(shù)據(jù)成員自身大小中更小的那個進行對齊。2. 整體對齊規(guī)則:struct或者union的首地址按照內(nèi)部最大數(shù)據(jù)成員的大小和#pragma pack數(shù)值較小的那個N進行對齊,并且結(jié)構(gòu)體的總大小為N的整數(shù)倍,如有必要編譯器也會在最后一個成員后面填充一些字節(jié)用于對齊。
如何進行內(nèi)存對齊
class?A
{用于創(chuàng)建一塊對齊的內(nèi)存
????int?a;
????char?d;
};
//?創(chuàng)建給定類型對象大小滿足對齊要求的未初始化內(nèi)存塊,在一個內(nèi)存對齊的緩沖區(qū)上創(chuàng)建對象
//?C 11后可以這樣操作
void?align_cpp11_after()
{
????static?std::aligned_storage<sizeof(A),
????????????????????????????????alignof(A)>::type?data;
????A?*attr?=?new?(