內存對齊

對齊緣由

爲了訪問未對齊的內存,處理器須要作兩次內存訪問。而對齊的內存只需作一次內存訪問。 一個字或雙字操做數跨越了4 字節邊界,或者一個四字操做數跨越了8 字節邊界,被認爲是未對齊的,從而須要兩次總線週期來訪問內存。一個字起始地址是奇數但卻沒有跨越字邊界被認爲是對齊的,可以在一個總線週期中被訪問。某些操做雙四字的指令須要內存操做數在天然邊界上對齊。若是操做數沒有對齊,這些指令將會產生一個通用保護異常。雙四字的天然邊界是 可以被16 整除的地址。其餘的操做雙四字的指令容許未對齊的訪問(不會產生通用保護異常),然而,須要額外的內存總線週期來訪問內存中未對齊的數據。php

對齊原則

  • 可是不論類型是什麼,對齊的邊界必定是1,2,4,8,16,32,64…中的一個。
  • 每一個成員分別按本身的方式對齊,並能最小化長度。
  • 複雜類型(如結構)的默認對齊方式是它最長的成員的對齊方式,這樣在成員是複雜類型時,能夠最小化長度。而後,對齊後的長度必須是成員中最大的對齊參數的整數倍,這樣在處理數組時能夠保證每一項都邊界對齊。
  • 自定義對齊邊界時:每一個成員按其類型的對齊參數(一般是這個類型的大小)和指定對齊參數(這裏是n 字節)中較小的一個對齊

編譯器對齊

缺省狀況下,編譯器默認將結構、棧中的成員數據進行內存對齊。css

自定義對齊

#pragma pack 的用法:
#pragma pack(push) //保存當前對齊方式到packing stack
#pragma pack(push,n) 等效於
#pragma pack(push)
#pragma pack(n) //n=1,2,4,8,16 保存當前對齊方式,設置按n 字節對齊。
#pragma pack(pop) //packing stack 出棧,並將對其方式設置爲出棧的對齊。
相關文章
相關標籤/搜索