2010-06-11 59 views
9

請原諒我,如果您覺得這已被多次回答,但我需要以下查詢的答案!CPU和數據對齊

  1. 爲什麼數據必須對齊(在4字節/ 8字節/ 2字節邊界上)?這裏我的疑問是,當CPU的地址線爲Ax Ax-1 Ax-2 ... A2 A1 A0時,很可能會依次尋址存儲單元。那麼爲什麼需要在特定的邊界上調整數據呢?

  2. 如何在編譯我的代碼並生成可執行文件時找到對齊要求?

  3. 如果例如數據對齊是4字節的邊界,這是否意味着每個連續的字節位於模4的偏移?我懷疑如果數據是4字節對齊的,這是否意味着如果一個字節在1004,那麼下一個字節在1008(或在1005)?

您的想法非常受歡迎。

提前致謝! /MS

回答

11

CPU是面向字的,不是面向字節的。在一個簡單的CPU中,內存通常被配置爲每個地址選通返回一個(32位,64位等),其中底部的兩個(或更多)地址線通常是無關位。

英特爾CPU可以執行訪問對許多指令的非字boundries,但是有一個性能損失來確定內部CPU執行兩個存儲器存取和一個數學運算以加載一個字。如果您正在進行字節讀取,則不應用對齊方式。

一些CPU(ARM或Intel SSE指令)要求對齊的內存和做未對齊的訪問時都未定義操作(或拋出異常)。它們通過不實現更復雜的加載/存儲子系統來節省大量的硅片空間。

對齊取決於CPU字長(16,32,64)或在SSE的情況下,SSE寄存器大小(128位)。

對於你的最後一個問題,如果你一次加載一個數據字節,大多數CPU沒有對齊限制(一些DSP沒有字節級指令,但很可能你不會碰到一個) 。

+0

hi發情, 這裏是我的懷疑了!爲什麼低2地址線被消除?考慮到這個設置,我只能訪問地址0,4,8等數據。以此類推。那麼在這種情況下如何處理字節操作呢?您提到,單個數據字節沒有對齊限制,當底部2個地址線不關心時如何實現? 謝謝您的回覆! – 2010-06-12 06:29:55

+0

大多數情況下,我擔心地址線爲什麼不在意在我的代碼中可能存在字節操作(並且一直執行相同的操作)? – 2010-06-12 06:35:57

2

一般來說,所有這三個問題的答案都是「這取決於你的系統」。一些更多細節:

  1. 您的內存系統可能不是字節尋址的。除此之外,您可能會因處理器訪問未對齊的數據而導致性能降低。有些處理器(比如舊的ARM芯片)根本無法做到。

  2. 閱讀手冊爲您的處理器和任何ABI規範正在爲生成代碼,

  3. 通常,當人指的是在一定的對準數據時,它僅僅是指第一個字節。因此,如果ABI規範說「數據結構X必須是4字節對齊的」,這意味着X應該放置在可被4整除的地址的內存中。關於結構X的大小或內部佈局沒有任何暗示。

    至於你具體的例子去,如果數據一致,起始地址爲1004 4字節,下一個字節將在1005

5

很少有數據需要對齊。更多的是某些類型的數據可能執行得更好,或者某些cpu操作需要某種數據對齊。

首先,假設您一次讀取4個字節的數據。我們還要說你的CPU有32位數據總線。我們還要說您的數據存儲在系統內存的字節2中。

現在,因爲你可以加載4個字節的數據一次,它並沒有什麼太大的意義有你的地址寄存器指向一個字節。通過使您的地址寄存器指向每4個字節,您可以操縱4次數據。因此,換句話說,你的CPU可能只能夠讀取數據的起始字節0,4,8,12,16,等

所以這裏的問題。如果你想開始字節2中的數據和你正在讀4個字節,則有一半的數據會在地址位置0,另一半在位置1

所以基本上你最終擊中內存的兩倍讀你的一個4字節的數據元素。某些CPU不支持這種操作(或強制您手動加載和合並兩個結果)。

去這裏的更多詳細信息:http://en.wikipedia.org/wiki/Data_structure_alignment

+5

+1,但您應該注意,只有一些處理器可以容忍未對齊的數據。英特爾爲IA32和IA64體系結構提供支持,但不支持安騰。您的解釋只適用於容許未對齊數據的處理器,如IA32/IA64。 Alpha AXP會產生錯誤,我認爲MIPS也是如此。有些操作系統會處理錯誤處理程序中的錯位數據,但性能損失非常大。如果操作系統無法處理它,那麼對於那些系統來說,錯位的數據無法工作。 – 2010-06-11 18:40:20

4

1)一些體系沒有這個要求不惜一切,一些鼓勵對齊(在訪問非alignet數據項,當速度上的懲罰),有的可強制執行它嚴格(錯誤導致處理器異常)。
許多今天的流行體系結構都屬於速度懲罰類別。 CPU設計人員必須在靈活性/性能和成本(硅面積/總線週期所需的控制信號數量)之間進行交易。

2.)什麼語言,哪種架構?請查閱編譯器手冊和/或CPU體系結構文檔。

3)再次,這是完全依賴於體系結構(某些體系結構可能不允許在字節大小的項的訪問在所有,或具有總線寬度,其甚至不8位的倍數)。所以除非你詢問特定的體系結構,否則你不會得到任何有用的答案。

-1

「現在,因爲你可以一次裝載4個字節的數據,它並沒有什麼太大的意義有你的地址寄存器指向一個字節。」

爲什麼?爲什麼我一次不能閱讀職位1,2,3,4?我認爲這樣做不會降低性能,並會導致電路複雜化?

+0

這不是一個答案。我注意到你已經把它變成了一個填充問題(http://stackoverflow.com/questions/3903164/why-misaligned-address-access-incur-2-or-more-accesses),這是正確的事情做。 – 2010-10-11 04:14:46

1

它完全取決於您使用的CPU!

某些體系結構只處理32位(或36位)的單詞,您需要特殊指令才能加載singel字符或haalf單詞。

某些CPU(尤其是PowerPC和其他IBM RISC芯片)不關心路線和從奇數地址加載整數。

對於大多數現代體系結構,您需要將整數與單詞邊界和長整數對齊以增加單詞邊界。這簡化了加載寄存器的電路並加快了速度。

1

由於性能原因,CPU需要數據對齊。英特爾網站給出了關於如何對齊數據存儲在存儲器

Data Alignment when Migrating to 64-Bit Intel® Architecture

其中的一個細節是數據項的調整 - 該地址分別是其相對於存儲位置四個,八個或十六個字節的倍數。在16位英特爾架構下,數據對齊對性能影響不大,其使用完全是可選的。在IA-32下,正確對齊數據可以是一個重要的優化,儘管它的使用仍然是可選的,只有少數例外,正確對齊是強制性的。然而,64位環境對數據項目提出了更嚴格的要求。未對齊的對象導致程序異常。要正確對齊項目,它必須滿足64位英特爾架構(稍後討論)的要求,以及用於構建應用程序的鏈接器的要求。

數據對齊的基本原則是最安全(也是最廣泛支持)的方法依賴於英特爾所稱的「自然界限」。這些是在將數據項的大小整理爲下一個最大大小爲2,4,8或16個字節時發生的情況。例如,一個10字節的浮點應該對齊一個16字節的地址,而64位的整數應該對齊到一個8字節的地址。由於這是一個64位體系結構,所以指針大小都是八個字節寬,所以它們也應該在八字節邊界上對齊。

建議所有大於16字節的結構在16字節邊界上對齊。在一般情況下,爲了獲得最佳性能,對齊數據如下:

  • 對齊在
  • 對齊的16位數據被包含的排列成行的4字節字內
  • 對齊32任何地址的8位數據位數據,以使得它的基地址是4
  • 對齊的64位數據的倍數,使得它的基地址是8
  • 對齊的80位數據的倍數,使得它的基地址是一個16歲
  • 的倍數
  • 對齊128位數據,以便其基地址是16的倍數

一個64字節或更大的數據結構或數組應對準,使得它的基地址爲64的減小的尺寸以便對數據進行排序的倍數是一個啓發式用於與輔助自然對齊。只要16個字節的邊界(和緩存行)永遠不會交叉,自然對齊並不是絕對必要的,但它是一種簡單的方法來強制遵守一般對齊建議。

在結構中正確對齊數據可能導致數據膨脹(由於填充需要正確放置字段),因此在必要和可能的情況下,重新組織結構以便需要最寬對齊的字段在結構中首先。有關解決此問題的更多信息,請參閱「準備IA-64體系結構代碼(代碼清理)」一文。