1. 程式人生 > >Intel Sandy Bridge/Ivy Bridge架構/微架構/流水線 (7) - 流水線前端/譯碼後指令快取

Intel Sandy Bridge/Ivy Bridge架構/微架構/流水線 (7) - 流水線前端/譯碼後指令快取

Decoded ICache

譯碼後微指令快取本質上是對傳統的譯碼流水線的快取記憶體加速器。通過快取微指令,可以提供如下的優勢:

  • 減少由於分支預測失敗導致的延遲
  • 增加發射微指令到亂序引擎的頻寬
  • 降低流水線前端的能耗

譯碼後微指令快取儲存指令譯碼器生成的微指令。以後當這些微指令需要被執行時,可以直接從快取中獲取,而不再需要這些微指令的取指和譯碼階段,從而節省前端的能耗,消除譯碼延遲。微指令快取提供大約80%的微指令命中率;而且,對於頻繁執行的“熱程式碼”通常可以達到100%的命中率。

典型的整型程式平均每條指令略小於4位元組,流水線前端的譯碼速度能夠“跑贏”後端的消費速度,可以填充一個較大的微指令緩衝區視窗,從而讓排程器發現可以並行的指令。但是對於高效能的程式,某些基本的程式碼塊由許多指令組成,例如Intel SSE媒體演算法或者重度的迴圈展開,每個週期譯碼16位元組指令流可能會到導致後端發生指令飢餓(即無指令可執行)。這時候面向32位元組的微指令快取可以幫助避免指令飢餓。

如果程式執行具有時間和空間區域性性,微指令快取可以自動地提升程式效能。但是要想充分地利用微指令快取的潛能,程式設計師還是需要了解一些快取的內部組織結構。

微指令快取由32個組(set)構成。每個組包含8路。每路可以儲存最多6條微指令。故整個快取可以儲存32*8*6=1536條微指令,即上面圖中顯示的1.5K uop cache。

下面是微指令快取中填充微指令的規則:

  • 每路中的所有微指令(最多6條)都必須來自於同一個靜態連續的程式碼塊,這些微指令的EIP必須位於同一個32位元組對齊的區域內。
  • 最多隻能有3路快取被分配給同一個32位元組對齊的程式碼區,即原始的IA程式中每32位元組的區域中最多可以有18條微指令可以被快取。
  • 多微指令的x86指令不能跨路儲存,即x86指令對應的多條微指令不能分別儲存在兩路中。
  • 每路中最多儲存兩條分支
  • 需要使用MSROM進行譯碼的指令會佔據整路快取
  • 每路中的非條件分支指令必須是最後一條微指令。
  • 微熔合的微指令(load + op和store)作為一條微指令快取
  • 巨集熔合的指令作為一條微指令快取
  • 帶有64位(8位元組)立即數的指令需要兩個快取槽(slot)來儲存資料。(注:大概每個slot是8位元組長,Intel文件未說明)

當微指令不滿足以上的條件限制,無法儲存在微指令快取中時,它們只能由傳統的譯碼流水線處理。一旦前端切換到傳統的譯碼流水線進行譯碼,只能等到下一個分支指令才能切換回從微指令快取中獲取微指令。所以頻繁的在“傳統譯碼流水線”與“微指令快取”之間切換會產生效能損失。

事實上,微指令快取是包含在一級指令快取和ITLB中的。即一級指令快取中儲存的x86指令與微指令快取中的微指令對應存在。一級指令快取中的快取行被決出(evicted)時,對應的微指令也會從微指令快取中被決出。

在某些情況下,整個微指令快取可能會被重新整理(fluashed)。一個原因可能是由於ITLB條目被決出。其他的原因通常是應用程式設計師不可見的,可能是由於某些重要的控制狀態發生了變化,例如,重新映射了CR3,或者CR0和CR4的某些特性或模式標誌位被啟用等。

注:CR3與虛擬地址轉換有關,CR0/CR4用於控制處理器的特性,例如開啟保護模式,分頁模式,實體地址擴充套件等。詳情可參看Intel SDM文件或https://en.wikipedia.org/wiki/Control_register

還存在一些情況會導致整個微指令快取被禁用,例如,當CS段暫存器的基地址是非0時。