2012-04-04 65 views
3

我對內存對齊的概念有點困惑。所以這裏是我的疑問: 什麼文字說的是,如果你想讀取4個字節的數據,從一個不能被4整除的地址開始,你就有了一個未對齊的內存訪問的情況。例如,如果我想從地址05開始讀取10個字節,這將被稱爲未對齊訪問(http://www.mjmwired.net/kernel/Documentation/unaligned-memory-access.txt)。內存地址對齊

請問這種情況是特定於4字節的字尋址體系結構還是這種保持字節可尋址體系結構的有效?如果上述情況未針對字節可尋址體系結構進行對齊,爲何如此?

謝謝!

+0

這是操作系統解決的問題之一...... – ControlAltDel 2012-04-04 20:40:58

+2

沒有我知道的處理器有10字節的數據類型。讓我們用一個32位數據總線的普通處理器來簡化它,並試圖從地址1讀取一個32位值。這要求首先讀取地址0處的值,將字節1移至偏移量0,移動字節2偏移1,移動字節3偏移2.然後讀取地址4的值,移動字節0的偏移量3.聲音涉及,不是:) – 2012-04-04 20:44:18

回答

3

作爲一般規則,存儲器中的位0被選通到總線上,並且該總線的位0連接到每個寄存器的位0。它繼續這樣直到第31位。可能有特殊的硬件將每個字節(比特15:8,23:16和31:24)指向低位字節,比特7:0。 (當你到了位「32」,它實際上是在地址4位的4字節字的0)

然而,額定情況有是移動字節之外的任何位置的任何特殊硬件比它們名義上以自然順序連接的那個,也可能是字節通道0。

想象一個簡單的帶32個數據引腳和32個數據引腳的簡單CPU的存儲器芯片。每個芯片上的給定數據引腳連接到另一個芯片上的相應引腳,並僅連接到那個芯片上。有簡單的是沒有辦法爲一個簡單的CPU來完成未對齊的讀取根本。

所以,從0開始考慮讀取。接下來的4個字節全部落入寄存器中,這是從地址4開始的。但是,如果從地址1讀取(32位),會發生什麼?還是2?還是3?雖然讀取不能直接在硬件中完成,但是花哨的控制器可能會導致很多事情發生:

  • CPU可以執行兩次讀取以獲取所有位。它不能同時做,它只有32個引腳。一次讀取來自地址0,另一次來自地址4
  • 然後,CPU必須執行各種移位,掩碼和包含或運算,以便從這兩個組件中構建單個字。

所有這些事情都需要額外的時間。


注意。實際上,數據總線通常是32位的倍數,存儲器也是如此。可能存在重新對齊對象的特殊硬件。但即使如此,因爲這是一個異常情況,它可能無法獲得正確對齊讀取的管道優化,即使使用特殊硬件,通過它運行操作數可能會有時間損失。

+0

謝謝你的例子! – 2012-06-02 08:20:47

0

對齊與數據大小和尋址有關。大多數指令集/軟件的尋址是以字節爲單位的。 0,1,2,3都是有效的字節地址。假設你正在訪問的內存系統或外設是「字節​​可尋址的」,基本上你可以寫入單個字節,你通常會有指令讓你使用任何地址值。如果對齊表示地址的lsbit爲零,則對齊開始於多個字節,兩個字節,未對齊表示它是一個字節。四個字節,32位數量,低兩位爲零,對齊,一個或兩個不爲零,未對齊,等等。可以認爲它是模的,你想要一個模4 = 0的地址在4字節邊界上對齊。

現在通常作爲一名軟件工程師,您不會故意將自己置於需要在地址5處獲得10個字節的情況,您可能會在0x4或0x0處執行12個字節或沿着這些行執行某些操作,即使你只能使用其中的10個,你會更符合邏輯地對齊它們。外部影響,網絡數據包,文件系統,共享內存,硬件等,任何時候你通過一個編譯域,你可能需要處理這個並採取相應的行動。 10個字節是半有趣的,取決於你是否試圖將這些字節複製到另一個同樣不好的地址,或者只是讀取它們或寫入它們。如果讀取你可能只想讀取地址爲0x4的12個字節並完成它。如果寫得很好,你可以在一個很好的循環中完成所有的10或者一次展開一個字節,你可以在0x5寫一個,在0x6寫兩個,在0x8寫四個,在0xC寫兩個,或者在0x5寫一個,循環或展開的4個16位值從0x6開始,然後在0xE處開始一個字節。等

既然你說讀取,你可以讀取0x4的3 32位數量或從0x0開始的兩個64位數量。這很大程度上取決於你打算如何處理數據以及你正在使用什麼指令集等。一個10字節的讀取循環可能是最簡單/最簡單的讀取,維護等。

如果你想知道對齊左右對齊VS那是因爲我與寫上面提到的,你可以做一個

8 bit access at 0x5 
16 bit access at 0x6 
32 bit access at 0x8 
16 bit access at 0xC 
8 bit access at 0xE 

,因爲我一直在說,雖然爲讀取可能不是最有效的。對於寫入,您可以讀取 - 修改32或64位數量的寫入或上述組合。