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