linux記憶體對齊

2021-06-19 05:29:44 字數 2084 閱讀 8521

一,記憶體位址對齊的概念

計算機記憶體中排列、訪問資料的一種方式,包含基本資料對齊和結構體資料對齊。

32位系統中,資料匯流排寬度為32,每次能夠讀取4位元組資料。位址匯流排為32,最大定址空間為4gb。但是由於最低位a[0]~a[1]是不用於定址的,因此只能訪問4的倍數的位址空間,但是定址空間還是2^30*字長=4gb。

因此記憶體中除了結構體中成員變數之外的基本型別的開始的手位址最低兩位都是0。基本型別資料對齊就是資料在記憶體中的偏移位址必須是乙個字的倍數,以提高讀取資料時的效能。為了對齊資料,必須在上個資料結束和下個資料開始處插入一些位元組,這就是結構體資料對齊。

二,記憶體對齊的原因

大部分的參考資料都是如是說的:

1、平台原因(移植原因):不是所有的硬體平台都能訪問任意位址上的任意資料 的;某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。

2、效能原因:資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。 原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問;而對齊的記憶體訪問僅需要一次訪問。

例如int a的位址是0x00fffff3,則其位元組分布在0x00fffff3~0x00fffff6空間內,為了讀取這個int,cpu必須對 0x00fffff0和0x00fffff4進行兩次記憶體讀取,並處理得出的中間結果。兩次記憶體訪問將會浪費大量的時間,因為記憶體訪問的速度遠小於cpu 處理指令的速度。

三、對齊規則

每個特定平台上的編譯器都有自己的預設「對齊係數」(也叫對齊模數)。程式設計師可以通過預編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一係數,其中的n就是你要指定的「對齊係數」。

規則:1、資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第乙個資料成員放在offset為0的地方,以後 每個資料成員的對齊按照#pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。

2、結構(或聯合)的整體對齊規則:在 資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。

3、結合1、2顆推斷:當#pragma pack的n值等於或超過所有資料成員長度的時候,這個n值的大小將不產生任何效果。

四,結構體的記憶體位址對齊

結構體本身必須是4位元組對齊的,而其成員變數則處理規則如下。

以下是microsoft和gnu對x86架構32位系統的結構體成員的預設對齊方式:

char  1位元組對齊

short  2位元組對齊

int 

4位元組對齊

float  4位元組對齊

double windows是8位元組對齊,linux是4位元組對齊

當某乙個成員後邊的成員變數要求的位址對齊較大,則應該填入一些位元組。且總的結構體大小為最大對齊的倍數,因此最後可能還要填充一些字元。

因為上述結構體對齊的原因,將結構體成員按照大小遞增/遞減方式排序,可以減少結構體占用的空間大小。而這樣同時使得對整個結構體的訪問的效率變高了(占用小,整個的訪問次數可以降低)。

另外乙個提高效率的方法是把一些占用位元組數較少的成員合併到位元組數占用大的成員,形成union型別。比如,

struct merge  }

占用為8位元組。初始化需要3次記憶體讀,3次賦值,3次記憶體寫。

struct unmerge

占用為12位元組。初始化需要2次記憶體讀,3次賦值,1次位移,2次記憶體寫。

但是用cpu的操作換取記憶體的讀寫可以很大的提高效能。基本上提高的效能比例等於記憶體訪問次數的較少數目和當前訪問次數的比例,此處為(6-4)/4=50%。

陣列或者結構體陣列只要保證首位址對齊,其中元素不要求對齊,因為對於陣列,其中任何元素都可以在1~2次記憶體訪問中獲取,對於結構體陣列,因為結構體內部是按照上述方式填充,則也不需要結構體陣列的元素都位址對齊。

對於效能要求較高的情況,比如tcp/ip協議的首部的定義,可以採用位段(bit-fields)的方式來對整數資料按照需要的字段數分配。當然,位段 只能對整數進行操作,如果float和int型別資料放在一起用位段方式顯然不行,但是通過位移的方法也可以把char型別資料併入float或者 double中。位段也需要遵循結構體對齊的方式。

五,使用者自定義

使用#pragma pack指令。

記憶體對齊 記憶體對齊規則解釋 記憶體對齊原理

一 記憶體對齊的原因 我們都知道計算機是以位元組 byte 為單位劃分的,理論上來說cpu是可以訪問任一編號的位元組資料的,我們又知道cpu的定址其實是通過位址匯流排來訪問記憶體的,cpu又分為32位和64位,在32位的cpu一次可以處理4個位元組 byte 的資料,那麼cpu實際定址的步長就是4個...

記憶體對齊(自然對齊)

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

位元組對齊 記憶體對齊 對齊粒度

其實標題裡面的三個關鍵字說的都是同乙個東西。也就是c 中類和結構體在記憶體中的分配策略,專業術語可以稱之為 對齊模數 alignment modules 對齊模數分為三類 1.自身對齊模數,也就是類或結構體中成員的大小,1,2,4,8之中的乙個,對應byte word dword qword。2.指...