計算中,快取控制指令是嵌入處理器指令流中的提示,旨在利用程式設計師編譯器提供的關於主記憶體訪問模式的資訊來提高硬件快取的效能。 [1]它們可以通過更好地控制工作集來減少快取污染英語Cache pollution、減少頻寬需求、繞過延遲。大多數快取控制指令不會影響程式的語意,儘管有些可以。

例子

此類指令受多個處理器指令集架構的支援,例如ARMMIPSPowerPCx86

預取

也稱為數據快取塊輕觸,其效果是請求載入與給定地址關聯的快取行。這是由x86指令集中的PREFETCH指令執行的。一些變體繞過更進階別的快取階層英語Cache hierarchy,這在「串流」上下文中對於遍歷一次而不是儲存在工作集中的數據很有用。預取應該發生得足夠早,以減輕主記憶體訪問的延遲,例如在使用迴圈來線性遍歷主記憶體時。 GCC內建函數__builtin_prefetch可用於在程式語言CC++中呼叫。

指令預取

預取的一種變體,適用於指令快取。

數據快取塊分配零

此提示用於在完全覆蓋內容之前準備快取行。在這個例子中,CPU 不需要從主主記憶體載入任何東西。語意效果等同於使用對齊的memset,將快取行大小的塊設為零,但操作實際上是實現釋放。

數據快取塊無效化

此提示用於丟棄快取行,而不將其內容提交到主主記憶體。該指令可能會帶來不正確的執行結果,因此需要謹慎使用。與其他快取提示不同,這條快取提示會極大地改變程式語意。這與allocate zero一起用於管理臨時數據。這節省了不需要的主主記憶體頻寬,避免快取污染。

數據快取塊重新整理

此提示請求立即犧牲一個快取行,為即將發生的分配讓路。當已知數據不再是工作集的一部分時使用它。

其他提示

一些處理器支援載入-儲存指令的變體,這些指令也包含快取提示。一個例子是PowerPC指令集中的load last ,這表明數據只會被使用一次,即相應快取行可能會被送到等待犧牲的佇列的頭部。

替代方案

自動預取

最近,英特爾ARM開發的越發先進的應用處理器將更多的電晶體用於加速用傳統語言編寫的代碼,例如執行自動預取、使用硬件來動態檢測線性訪問模式。因而快取控制指令變得不那麼流行了。然而,這些技術可能對面向吞吐量的處理器仍然有效,它們具有不同的吞吐量-延遲的側重性,並且可能更傾向將更多區域用於執行單元。

暫存器主記憶體

一些處理器支援將臨時檔案放入暫存器英語scratchpad memory,並使用直接記憶體存取(DMA)在需要時將數據傳入傳出主主記憶體Cell 處理器和一些嵌入式系統使用這種方法。這些允許更好地控制主記憶體流量和位置(因為工作集由顯式傳輸管理),並消除了對多核機器中昂貴的快取一致性的需求。

缺點是它需要使用截然不同的編程技術。很難覆寫用傳統語言(如 C 和 C++)編寫的程式,這些語言向程式設計師提供了一個大地址空間的統一視角(這是通過快取模擬出來的錯覺)。傳統的微處理器可以更輕鬆地執行遺留代碼,然後可以通過快取控制指令對其進行加速,而基於暫存器的機器則需要從頭開始進行專門編寫,直至能實現相同功能。快取控制指令特定於某個快取行大小,在實踐中,同一體系結構系列中的處理器各代之間可能不同。快取還可以幫助從不可預測的訪問模式(例如,在材質貼圖的過程)中合併讀取和寫入,而暫存器 DMA 需要重新設計演算法以實現更可預測的「線性」遍歷。

此類暫存器通常更難與傳統編程模型一起使用,不過對於資料流模型(例如TensorFlow)而言可能更合適。

向量讀取

向量處理器(例如現代圖形處理單元(GPU) 和Xeon Phi)使用大規模平行計算來實現高吞吐量,同時解決主記憶體延遲問題(減少預取的需要)。許多讀取操作是並列發出的,用於計算內核的後續呼叫;計算可能會暫停以等待後續的數據,而執行單元則盡力處理來自過去收到的請求的數據。對於程式設計師來說,這種模式更容易與適當的編程模型(內核函數)結合使用,但更難應用於通用編程。

缺點是臨時狀態的許多副本可能儲存在處理元素的本地主記憶體中,等待傳輸中的數據。

參考資料

Wikiwand in your browser!

Seamless Wikipedia browsing. On steroids.

Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.

Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.