淺析爲何要內存對齊

在分析內存對其之前,先簡要簡要介紹一下ARM處理器是如何進行數據操作的:

     ARM是32位處理器,armv4能高效的處理8,16,32位的數據,但是大多數arm處理器直接操作的是32位的數據。

地址跳變基數爲4字節即4.一次存取數據量爲32位。(硬件角度),我們一次取到的32位數據不一定是一個完整

的數據構,可能是兩個數據結構,也可能是某個數據結構的一部分,(而編譯器幫助我們將一條對數據結構操作

的C操作轉化成多條對齊的彙編指令,這些從每次取到的32位數據中獲得有用的值,合併重組而完成對一個數據結構的操作)

當對一個數據結構進行操作時,如邊界不對齊,編譯器可以將C操作轉化成多條邊界對齊的彙編操作,把結果合併、

重組來模擬對齊的操作(可見這種非對齊的存儲是非常消耗效率的)。

軟件角度,在軟件方面我們定義的數據排列方式是由編譯器決定的,根據編譯器的對稱規則進行數據排列,而常用的

數據操作指令(ARM指令中的)是以4字節爲對稱邊界進行操作的。C中允許你干預“內存對齊”。

上面已經提到了,內存對齊對處理器效率的影響,而我們關注內存對齊不外乎下面兩大原因:

     1、平臺原因(移植原因):不是所有的硬件平臺都能訪問任意地址上的任意數據的;某些硬件平臺只能在某些地址處取

某些特定類型的數據,否則拋出硬件異常。(平臺移植是驅動程序開發者經常需要考慮的問題)。

      2、性能原因:數據結構(尤其是棧)應該儘可能地在自然邊界上對齊。原因在於,爲了訪問未對齊的內存,處理器需要

作兩次內存訪問;而對齊的內存訪問僅需要一次訪問。(就是剛纔所提到的對效率的影響)。

     下面簡要說明下內存對齊對高質量可移植代碼的重要性:

     在arm處理器中如果裝載和存儲的地址與數據類型的邊界不對齊,那麼可能產生異常的結果,例如:通常C編譯器假定

指針是邊界對齊的。如果指針不是邊界對齊,那麼程序執行會產生不正確的結果。這樣,把代碼從允許邊界不對齊的

處理器移植到ARM處理器時就會出現問題。

最後再提一下對齊規則:

對齊規則

  每個特定平臺上的編譯器都有自己的默認“對齊係數”(也叫對齊模數)。程序員可以通過預編譯命令#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值的大小將不產生任何效果。

 

文章轉自http://blog.csdn.net/liukun321/article/details/6974206

發佈了21 篇原創文章 · 獲贊 5 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章