Appendix B Review of Memory Hierarchy
本附錄是對內存層次結構的快速復習,包括緩存和虛擬內存、性能方程和簡單的優化。 這第一部分回顧了以下 36 個術語:
如果此評論進行得太快,您可能需要查看計算機組織和設計中的第 7 章,這是我們為經驗較少的讀者編寫的。
緩存是地址離開處理器后所遇到的最高或第一級內存層次結構的名稱。 因為局部性原則適用于許多級別,并且利用局部性來提高性能很流行,所以現在只要使用緩沖來重用常見的項目,就會應用術語緩存。 示例包括文件緩存、名稱緩存等。
當處理器在緩存中找到請求的數據項時,稱為緩存命中。 當處理器在緩存中找不到它需要的數據項時,就會發生緩存未命中。 包含所請求字的固定大小的數據集合,稱為塊或行運行,從主存儲器中檢索并放入緩存中。時間局部性告訴我們,在不久的將來我們可能會再次需要這個詞,因此將它放在可以快速訪問的緩存中很有用。由于空間局部性,很可能很快就會需要塊中的其他數據。
緩存未命中所需的時間取決于內存的延遲和帶寬。 延遲決定了檢索塊第一個字的時間,帶寬決定了檢索該塊其余部分的時間。緩存未命中由硬件處理并導致使用有序執行的處理器暫停或停止,直到數據可用。 對于亂序執行,使用結果的指令仍必須等待,但其他指令可能會在未命中期間繼續執行。
同樣,并非程序引用的所有對象都需要駐留在主內存中。 虛擬內存意味著一些對象可能駐留在磁盤上。 地址空間通常分為固定大小的塊,稱為頁。 在任何時候,每個頁面都駐留在主內存或磁盤上。 當處理器引用緩存或主內存中不存在的頁面中的項目時,會發生 palt,整個頁面從磁盤移動到主內存。 因為頁面錯誤需要很長時間,所以它們在軟件中處理并且處理器不會停止。 當磁盤訪問發生時,處理器通常會切換到其他一些任務。 從高層次的角度來看,對引用局部性的依賴以及緩存與主內存的大小和相對成本的相對關系與主內存與磁盤的相關性相似。
圖 B.1 顯示了從高端臺式機到低端服務器的計算機的內存層次結構中每個級別的大小范圍和訪問時間。
Cache Performance Review
由于較小內存的局部性和更高的速度,內存層次結構可以顯著提高性能。 評估緩存性能的一種方法是擴展第 1 章中的處理器執行時間方程。我們現在考慮處理器停滯等待內存訪問的周期數,我們稱之為內存停滯周期。 性能是時鐘周期時間與處理器周期和內存停頓周期之和的乘積:
此等式假設 CPU 時鐘周期包括處理高速緩存命中的時間,并且處理器在高速緩存未命中期間停頓。 B.2 節重新審視了這個簡化的假設。
內存停頓周期數取決于未命中數和每次未命中的成本,稱為未命中懲罰:
最后一種形式的優點是可以輕松測量組件。 我們已經知道如何測量指令數 (IC)。 (對于推測處理器,我們只計算提交的指令。)可以用同樣的方式測量每條指令的內存引用數; 每條指令都需要指令訪問,并且很容易決定它是否也需要數據訪問。
請注意,我們將未命中懲罰計算為平均值,但我們將在此處使用它,就好像它是一個常數一樣。 由于先前的內存請求或內存刷新,緩存后面的內存可能在未命中時很忙。 處理器、總線和存儲器的不同時鐘之間的接口處的時鐘周期數也不同。 因此,請記住,使用單個數字進行未命中懲罰是一種簡化。
組件未命中率只是導致未命中的緩存訪問的分數(即未命中的訪問次數除以訪問次數)。 可以使用高速緩存模擬器測量未命中率,該模擬器獲取指令和數據引用的地址跟蹤,模擬高速緩存行為以確定哪些引用命中和哪些未命中,然后報告命中和未命中總數。 今天許多微處理器提供硬件來計算未命中和內存引用的數量,這是一種更容易和更快的測量未命中率的方法。
前面的公式是一個近似值,因為讀取和寫入的未命中率和未命中懲罰通常不同。 然后可以根據每條指令的內存訪問次數、讀取和寫入的未命中懲罰(以時鐘周期為單位)以及讀取和寫入的未命中率來定義內存停頓時鐘周期:
我們通常通過組合讀取和寫入并找到讀取和寫入的平均未命中率和未命中懲罰來簡化完整公式:
未命中率是緩存設計最重要的衡量標準之一,但正如我們將在后面的部分中看到的,它不是唯一的衡量標準。
一些設計人員更喜歡將未命中率測量為每條指令的未命中數,而不是每個內存引用的未命中數。 這兩個是相關的:
當您知道每條指令的平均內存訪問次數時,后一個公式很有用,因為它允許您將未命中率轉換為每條指令的未命中,反之亦然。 例如,我們可以將以下示例中的每個內存引用的未命中率轉換為每條指令的未命中率:
順便說一下,每條指令未命中通常報告為每 1000 條指令未命中,以顯示整數而不是分數。 因此,前面的答案也可以表示為每 1000 條指令 30 次未命中。
每條指令未命中的優點是它獨立于硬件實現。 例如,推測處理器獲取的指令數量大約是實際提交的指令數量的兩倍,如果以每個內存引用而不是每個指令的未命中來衡量,這可以人為地降低未命中率。 缺點是每條指令的缺失取決于體系結構; 例如,對于 80x86 與 RISC V,每條指令的平均內存訪問次數可能會有很大不同。 因此,每條指令的未命中在使用單個計算機系列的架構師中最為流行,盡管 RISC 架構的相似性允許人們和其他人對比。
Four Memory Hierarchy Questions
我們通過回答內存層次結構第一級的四個常見問題來繼續介紹緩存
這些問題的答案有助于我們理解在不同層次的層次上的記憶的不同權衡; 因此,我們對每個示例都提出這四個問題。
Q1: Where Can a Block be Placed in a Cache?
圖 B.2 顯示了對塊放置位置的限制創建了三類緩存組織:
圖B.2 This example cache has eight block frames and memory has 32 blocks. 緩存的三個選項從左到右顯示。 在完全關聯的情況下,來自較低級別的塊 12 可以進入緩存的八個塊幀中的任何一個。 對于直接映射,塊 12 只能放入塊幀 4(12 模 8)中。 Set associative 具有這兩種功能中的一些,允許將塊放置在 set 0(12 模 4)中的任何位置。 每組兩個塊,這意味著塊 12 可以放置在緩存的塊 0 或塊 1 中。 真實緩存包含數千個塊幀,而真實內存包含數百萬個塊。 集合關聯組織有四個集合,每個集合有兩個塊,稱為雙向集合關聯。 假設緩存中沒有任何內容,并且所討論的塊地址標識較低級別的塊 12。
- 如果每個塊只有一個地方可以出現在緩存中,則稱緩存是直接映射的。 映射通常是
- 如果塊可以放置在緩存中的任何位置,則稱該緩存是完全關聯的。
- 如果一個塊可以放置在緩存中的一組受限位置中,則緩存設置為關聯的。 集合是緩存中的一組塊。 一個塊首先被映射到一個集合,然后該塊可以放置在該集合內的任何位置。 該集合通常通過位選擇來選擇; 那是,
如果集合中有 n 個塊,則緩存放置稱為 n 路集合關聯。
從直接映射到完全關聯的緩存范圍實際上是集合關聯性級別的連續統。 直接映射只是單向集合關聯,具有 m 個塊的完全關聯緩存可以稱為“m 路集合關聯”。 等價地,直接映射可以被認為具有 m 個集合,而完全關聯的可以被認為具有一個集合。
當今絕大多數處理器緩存都是直接映射、二路組關聯或四路組關聯,原因我們將很快看到。
Q2: How Is a Block Found If It Is in the Cache?
緩存在每個塊幀上都有一個地址標簽,用于提供塊地址。 檢查可能包含所需信息的每個緩存塊的標記,以查看它是否與來自處理器的塊地址匹配。 通常,并行搜索所有可能的標簽,因為速度至關重要。 必須有辦法知道緩存塊沒有有效信息。 最常見的過程是向標簽添加一個有效位,以說明該條目是否包含有效地址。 如果未設置該位,則此地址無法匹配。
在繼續下一個問題之前,讓我們探討一下處理器地址與緩存的關系。 圖 B.3 顯示了地址是如何劃分的。 第一個劃分是在塊地址和塊偏移之間。 塊幀地址可以進一步分為標簽字段和索引字段。 塊偏移字段從塊中選擇所需的數據,索引字段選擇集合,標簽字段與它進行比較以獲得命中。 雖然可以在比標簽更多的地址上進行比較,但沒有必要,因為以下幾點:
- 在比較中不應使用偏移量無論整個塊是否存在,因為根據定義,所有塊偏移都會導致匹配。
- 檢查索引是多余的,因為它用于選擇要檢查的集合。 例如,存儲在集合 0 中的地址必須在索引字段中為 0,否則無法存儲在集合 0 中; set 1 的索引值必須為 1; 等等。 此優化通過減少緩存標簽的內存大小寬度來節省硬件和電源。
如果總緩存大小保持不變,增加關聯性會增加每個集合的塊數,從而減少索引的大小并增加標簽的大小。 也就是說,圖 B.3 中的標簽-索引邊界隨著關聯性的增加向右移動,完全關聯緩存的端點沒有索引字段。
Q3: Which Block Should be Replaced on a Cache Miss?
當發生未命中時,緩存控制器必須選擇要替換為所需數據的塊。 直接映射布局的一個好處是簡化了硬件決策——事實上,如此簡單以至于沒有選擇:只檢查一個塊幀是否命中,并且只有該塊可以被替換。 通過完全關聯或設置關聯放置,有許多塊可供選擇。 選擇要替換的塊時采用了三種主要策略:
- 隨機 - 為了均勻分布分配,隨機選擇候選塊。 一些系統生成偽隨機塊號以獲得可重現的行為,這在調試硬件時特別有用。
- 最近最少使用(LRU)——為了減少丟棄很快需要的信息的機會,對塊的訪問被記錄下來。 依靠過去來預測未來,被替換的塊是最長時間未被使用的塊。 LRU 依賴于局部性的一個推論:如果最近使用的塊很可能會再次使用,那么一個很好的處理候選者是最近最少使用的塊。
- 先進先出 (FIFO)——因為 LRU 計算起來很復雜,這通過確定最舊的塊而不是 LRU 來近似 LRU。
隨機替換的一個優點是可以簡單地構建硬件。隨著要跟蹤的塊數量的增加,LRU 變得越來越昂貴并且通常只是近似值。一個常見的近似(通常稱為pseudoLRU)在緩存中為每個集合都有一組位,每個位對應一個單路(一個路是組關聯緩存中的組;四路組關聯緩存中有四個路)在緩存中。當一個集合被訪問時,對應于包含所需塊的路的位被打開;如果與一組關聯的所有位都打開,則除了最近打開的位之外,它們都將復位。當一個塊必須被替換時,處理器從其位被關閉的方式中選擇一個塊,如果有多個選擇可用,通常是隨機的。這近似于 LRU,因為自上次訪問集合中的所有塊以來,將不會訪問被替換的塊。圖 B.4 顯示了 LRU、隨機和 FIFO 替換之間的未命中率差異。
Q4: What Happens on a Write?
讀取控制處理器緩存訪問。 所有指令訪問都是讀取,并且大多數指令不會寫入內存。 附錄 A 中的圖 A.32 和 A.33 建議 RISC V 程序混合使用 10% 存儲和 26% 加載,使寫入占總內存的 10%/(100%+26%+10%) 或大約 7% 交通。 在數據緩存流量中,寫入是 10%/(26%+10%) 或大約 28%。 使常見情況快速意味著優化讀取緩存,特別是因為處理器傳統上等待讀取完成但不需要等待寫入。 然而,阿姆達爾定律(第 1.9 節)提醒我們,高性能設計不能忽視寫入速度。
幸運的是,常見的案例也是容易快速制作的案例。 可以在讀取和比較標記的同時從緩存中讀取塊,因此一旦塊地址可用,塊讀取就開始。 如果讀取命中,則塊的請求部分會立即傳遞給處理器。 如果錯過,除了臺式機和服務器計算機的更多功能之外,沒有好處也沒有壞處; 只需忽略讀取的值。
寫操作不允許這種樂觀情緒。 在檢查標記以查看地址是否命中之前,無法開始修改塊。 由于標記檢查不能并行進行,因此寫入通常比讀取花費的時間更長。 另一個復雜性是處理器還指定了寫入的大小,通常在 1 到 8 個字節之間; 只能更改塊的那部分。 相比之下,讀取可以毫無顧慮地訪問比必要更多的字節。
寫策略通常區分緩存設計。 寫入緩存時有兩個基本選項:
直寫—信息被寫入緩存中的塊和低級內存中的塊
回寫——信息僅寫入緩存中的塊。 修改后的緩存塊只有在被替換時才會寫入主內存。
為了減少在替換時回寫塊的頻率,通常使用稱為臟位的功能。 此狀態位指示塊是臟的(在緩存中時被修改)還是干凈的(未修改)。 如果它是干凈的,則該塊不會在未命中時寫回,因為在較低級別中可以找到與緩存相同的信息。
回寫和直寫都有其優點。 使用回寫,寫入以高速緩存存儲器的速度發生,并且塊內的多次寫入只需要向較低級別的存儲器寫入一次。 由于某些寫入不會進入內存,因此回寫使用較少的內存帶寬,這使得回寫在多處理器中具有吸引力。 由于回寫使用剩余的內存層次結構和內存互連比直寫少,因此它還可以節省功耗,使其對嵌入式應用程序具有吸引力。
直寫比回寫更容易實現。 緩存始終是干凈的,因此與回寫讀未命中不同,永遠不會導致寫入到較低級別。 直寫還具有下一個較低級別具有數據的最新副本的優點,這簡化了數據一致性。 數據一致性對于多處理器和 I/O 很重要,我們在第 4 章和附錄 D 中進行了檢查。 多級緩存使上層緩存的直寫更可行,因為寫入只需要傳播到下一個較低級別而不是全部 到主存的方式。
正如我們將看到的,I/O 和多處理器是善變的:他們希望為處理器緩存寫回以減少內存流量并通過直寫來保持緩存與較低級別的內存層次結構保持一致。
當處理器在直寫期間必須等待寫入完成時,處理器被稱為寫停頓。 減少寫停頓的常見優化是寫緩沖區,它允許處理器在數據寫入緩沖區后立即繼續,從而使處理器執行與內存更新重疊。 正如我們將很快看到的,即使使用寫緩沖區也可能發生寫停頓。
由于寫入時不需要數據,因此寫入未命中有兩種選擇:
寫分配——在寫未命中時分配塊,然后是之前的寫命中操作。 在這個自然選項中,寫未命中就像讀未命中一樣。
無寫分配——這個明顯不尋常的替代方案是寫未命中不影響緩存。 相反,該塊僅在較低級別的內存中被修改。
因此,在程序嘗試讀取塊之前,塊在無寫分配中保持在緩存之外,但即使只寫入的塊仍將在具有寫分配的緩存中。 讓我們看一個例子。
寫入未命中策略可以與直寫或回寫一起使用。 通常,回寫緩存使用寫分配,希望對該塊的后續寫入將被緩存捕獲。 直寫緩存通常使用無寫分配。 理由是,即使對該塊有后續寫入,寫入仍然必須到較低級別的內存中,那么有什么好處呢?
An Example: The Opteron Data Cache
圖 B.5 顯示了 AMD Opteron 微處理器中數據緩存的組織結構,為這些想法提供了實質內容。 高速緩存包含 64 字節塊中的 65,536 (64 K) 字節數據,具有雙向設置關聯放置、最近最少使用的替換、回寫和寫未命中時的寫分配。
讓我們按照圖 B.5 中標記的命中步驟來跟蹤緩存命中。 (四個步驟顯示為帶圓圈的數字。)如 B.5 節所述,Opteron 向緩存提供 48 位虛擬地址以進行標記比較,同時將其轉換為 40 位物理地址。
Opteron不使用所有64位虛擬地址的原因是其設計人員尚不考慮任何人需要這么多的虛擬地址空間,并且較小的尺寸簡化了Opteron虛擬地址映射。設計人員計劃在未來的微處理器中展現虛擬地址。
進入緩存的物理地址分為兩個字段:34 位塊地址和 6 位塊偏移(64=2^6 和 34 + 6=40)。 塊地址進一步分為地址標簽和緩存索引。 步驟 1 顯示了這種劃分。
緩存索引選擇要測試的標簽以查看所需塊是否在緩存中。 索引的大小取決于緩存大小、塊大小和集合關聯性。對于 Opteron 緩存,集合關聯性設置為 2,我們計算索引如下:
因此,索引為 9 位寬,標簽為 34%9 或 25 位寬。 盡管這是選擇正確塊所需的索引,但 64 字節比處理器想要一次消耗的要多得多。 因此,將高速緩存的數據部分組織為 8 字節寬更有意義,這是 64 位 Opteron 處理器的自然數據字。 因此,除了用于索引正確緩存塊的 9 位之外,來自塊偏移的另外 3 位用于索引正確的 8 字節。 索引選擇是圖 B.5 中的步驟 2。
從緩存中讀取兩個標簽后,將它們與來自處理器的塊地址的標簽部分進行比較。 此比較是圖中的第 3 步。 為了確保標簽包含有效信息,必須設置有效位,否則比較結果將被忽略。
假設一個標簽匹配,最后一步是通過使用來自 2:1 多路復用器的獲勝輸入,向處理器發出信號以從緩存加載正確的數據。 Opteron 允許這四個步驟有 2 個時鐘周期,因此如果接下來的 2 個時鐘周期中的指令嘗試使用加載結果,它們將等待。
處理寫入比處理 Opteron 中的讀取更復雜,因為它在任何緩存中。 如果要寫入的字在緩存中,前三步是一樣的。 因為 Opteron 是亂序執行的,只有在它發出指令已經提交并且緩存標記比較表明命中后,數據才會寫入緩存。
到目前為止,我們已經假設了緩存命中的常見情況。 錯過了怎么辦? 在讀取未命中時,緩存向處理器發送一個信號,告訴它數據尚不可用,并從層次結構的下一級讀取 64 字節。延遲是塊的前 8 個字節的 7 個時鐘周期,然后是塊的其余部分的每 8 個字節的 2 個時鐘周期。 因為數據緩存是關聯的,所以可以選擇替換哪個塊。 Opteron 使用 LRU,它選擇引用時間最長的塊,因此每次訪問都必須更新 LRU 位。 替換塊意味著更新數據、地址標簽、有效位和 LRU 位。
由于 Opteron 使用回寫,舊數據塊可能已被修改,因此不能簡單地丟棄。 Opteron 為每個塊保留 1 個臟位以記錄該塊是否已寫入。 如果“受害者”被修改,它的數據和地址被發送到受害者緩沖區。 (這個結構類似于其他計算機中的寫緩沖區。)Opteron 有八個受害者塊的空間。 與其他緩存操作并行,它將犧牲塊寫入層次結構的下一個級別。 如果受害者緩沖區已滿,則緩存必須等待。
寫未命中與讀未命中非常相似,因為 Opteron 會在讀或寫未命中時分配塊。
我們已經看到了它是如何工作的,但是數據緩存不能滿足處理器的所有內存需求:處理器還需要指令。 盡管單個緩存可以嘗試同時提供兩者,但它可能是一個瓶頸。 例如,當執行加載或存儲指令時,流水線處理器將同時請求數據字和指令字。 因此,單個緩存會給加載和存儲帶來結構性危害,導致停頓。 解決這個問題的一種簡單方法是將其劃分:一個緩存專用于指令,另一個專用于數據。 在最新的處理器中可以找到單獨的緩存,包括 Opteron。因此,它具有 64 KiB 指令緩存和 64 KiB 數據緩存。
處理器知道它發出的是指令地址還是數據地址,因此兩者可以有單獨的端口,從而使存儲器層次結構和處理器之間的帶寬加倍。 單獨的緩存還提供了單獨優化每個緩存的機會:不同的容量、塊大小和關聯性可能會帶來更好的性能。 (與 Opteron 的指令緩存和數據緩存相反,術語統一或混合適用于可以包含指令或數據的緩存。)
圖 B.6 顯示指令緩存的未命中率低于數據緩存。 分離指令和數據消除了由于指令塊和數據塊之間的沖突而導致的未命中,但分離也固定了專用于每種類型的緩存空間。 錯過率哪個更重要? 單獨的指令和數據緩存與統一緩存的公平比較要求總緩存大小相同。 例如,單獨的 16 KiB 指令緩存和 16 KiB 數據緩存應該與 32 KiB 統一緩存進行比較。 使用單獨的指令和數據緩存計算平均未命中率需要了解每個緩存的內存引用百分比。 從附錄 A 中的數據我們發現分裂是100%/(100% + 26% + 10%) 或大約 74% 的指令參考 (26% + 10%)/(100% + 26% + 10%) 或大約 26% 的數據參考。 拆分對性能的影響超出了未命中率變化所指示的范圍,我們很快就會看到。
總結
以上是生活随笔為你收集整理的Appendix B Review of Memory Hierarchy的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 球差透射电镜测试服务的收费标准和样品要求
- 下一篇: 敏涵国际品牌:定义高端美妆新力量