簡體   English   中英

為什么 CPU 在字邊界上訪問內存?

[英]Why does CPU access memory on a word boundary?

我聽說過很多數據應該在內存中正確對齊以提高訪問效率。 CPU 在字邊界上訪問內存。

因此,在以下場景中,CPU 必須進行 2 次內存訪問才能獲得單個字。

Supposing: 1 word = 4 bytes

("|" stands for word boundary. "o" stands for byte boundary)


|----o----o----o----|----o----o----o----|   (The word boundary in CPU's eye)
           ----o----o----o----              (What I want to read from memory)

為什么會發生這種情況? CPU只能在字邊界讀取的根本原因是什么?

如果 CPU 只能在 4 字節字邊界訪問,那么地址線應該只需要 30bit,而不是 32bit 寬度。 因為最后 2 位在 CPU 眼中總是 0。

添加 1

更有什者,如果我們承認CPU必須在字邊界讀取,為什么邊界不能我想讀取的地方開始呢? 似乎邊界在 CPU 眼中是固定的。

添加 2

根據AnT ,似乎邊界設置是硬連線的,並且是由內存訪問硬件硬連線的。 就此而言,CPU 只是無辜的。

在這種情況下,“可以”(在“...CPU 可以訪問...”中)的含義取決於硬件平台。

在 x86 平台上,CPU 指令可以訪問絕對任何邊界對齊的數據,而不僅僅是“字邊界”。 未對齊訪問可能比對齊訪問效率低,但其原因與 CPU 完全無關。 它與底層低級內存訪問硬件的工作方式有關。 在這種情況下,與內存相關的硬件很可能必須對實際內存進行兩次訪問,但這是 CPU 指令不知道也不需要知道的事情。 就 CPU 而言,它可以訪問任何邊界上的任何數據。 其余部分對 CPU 指令是透明的。

在 Sun SPARC 等硬件平台上,CPU無法訪問未對齊的數據(簡單來說,如果您嘗試這樣做,您的程序就會崩潰),這意味着如果由於某種原因您需要執行這種未對齊的訪問,您必須實現手動顯式:將其拆分為兩個(或更多)CPU 指令,從而顯式執行兩個(或更多)內存訪問。

至於為什么會這樣……好吧,這就是現代計算機內存硬件的工作原理。 數據必須對齊。 如果未對齊,則訪問效率較低或根本不起作用。

現代記憶的一個非常簡化的模型是一個單元格(行和列),每個單元格存儲一個數據字。 可編程機械臂可以將單詞放入特定單元格並從特定單元格中檢索單詞。 一次一個。 如果您的數據分布在多個單元格中,您別無選擇,只能使用該機械臂進行多次連續旅行。 在某些硬件平台上,組織這些連續行程的任務對 CPU 是隱藏的(這意味着手臂本身知道如何從幾個部分組裝必要的數據),在其他平台上它對 CPU 是可見的(意味着它是CPU 負責組織這些手臂的連續行程)。

如果您可以對地址做出某些假設(例如“底部n位為零”),則可以節省尋址邏輯中的硅。某些 CPU(x86 及其類似產品)會將邏輯放置到位,將未對齊的數據轉換為多次獲取,從而隱藏程序員的一些令人討厭的性能影響。該世界之外的大多數 CPU 反而會引發硬件錯誤,明確地解釋他們不喜歡這個。

你將聽到的關於“效率”的所有論點都是胡說八道,或者更准確地說,是在回避這個問題。 真正的原因很簡單,如果可以減少操作的地址位數,則可以節省處理器內核中的硅。 由未對齊訪問(如在 x86 世界中)引起的任何低效率都是硬件設計決策的結果,而不是一般尋址所固有的。

話雖如此,對於大多數用例,硬件設計決策是有意義的。 如果您以兩字節字訪問數據,最常見的用例是訪問offset ,然后是offset+2 ,然后是offset+4等等。 能夠在訪問兩字節字時按字節遞增地址通常(如 99.44% 肯定)不是您想要做的。 因此,要求地址偏移量在字邊界上對齊並沒有什么壞處(設計數據結構時,這是一種輕微的一次性不便),但確實可以節省硅片。

撇開歷史不談,我曾經在 Interdata Model 70 上工作過一次——一台 16 位小型計算機。 它要求所有內存訪問都是 16 位對齊的。 按照當時的標准,當我處理它時,它的內存量也非常小。 (即使在當時它也是一個遺物。)字對齊被用來將內存容量加倍,因為繞線的 CPU 很容易被黑客入侵。 添加了新的地址解碼邏輯,在地址的低位取 1(以前是對齊錯誤)並用它切換到第二個內存庫。 嘗試沒有對齊邏輯! :)

因為效率更高。

在您的示例中,CPU 必須進行兩次讀取:它必須讀取前半部分,然后分別讀取后半部分,然后將它們重新組合在一起進行計算。 如果數據正確對齊,這比一次性讀取要復雜和慢得多。

一些處理器,如 x86,可以容忍未對齊的數據訪問(因此您仍然需要所有 32 位)——其他的如 Itanium 絕對無法處理未對齊的數據訪問,並且會非常抱怨。

字對齊不僅是 CPU 的特色

在硬件級別,大多數 RAM 模塊都具有與每個讀/寫周期可以訪問的位數相關的給定字大小。

在我必須與嵌入式設備接口的模塊上,尋址是通過三個參數實現的: 該模塊被組織成四個組,可以在 RW 操作之前進行選擇。 每個銀行本質上都是一個大表 32 位字,可以通過行和列索引進行尋址。

在這個設計中,每個單元只能訪問,所以每次讀操作返回 4 個字節,每個寫操作需要 4 個字節。

連接到該 RAM 芯片的內存控制器可以通過兩種方式設計:允許使用多個周期不受限制地訪問內存芯片以將未對齊的數據拆分/合並到/來自多個單元(使用附加邏輯),或者對如何進行一些限制可以在降低復雜性的情況下訪問內存。

由於復雜性會阻礙可維護性和性能,大多數設計師選擇了后者 [需要引用]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM