1. 程式人生 > >Pentium Pro流水線及其優化 (2)

Pentium Pro流水線及其優化 (2)

Pentium Pro Instruction Pipeline Details

處於講解指令流水線的需要,接下來我們詳細的講解一下Pentium Pro微架構中的相關單元。上圖是Pentium Pro處理器微架構的功能框圖,從中可以看到一些功能模組和子系統

  • 記憶體子系統 – 系統匯流排,二級指令/資料合併快取,匯流排介面單元,一級指令快取,一級資料快取,記憶體介面單元和記憶體訪問排序快取區
  • 取指/譯碼單元 – 指令預取單元,分支目標快取區,指令譯碼器,微指令序列器,和暫存器別名表
  • 微指令池 – 微指令排序快取區
  • 分發/執行單元 – 執行資源分配站,兩個整型單元,兩個浮點單元,和兩個地址計算單元
  • 終了單元– 終了單元和終了暫存器堆

Memory Subsystem

Pentium Pro處理器的記憶體子系統由系統DRAM記憶體,一級快取,二級快取構成。

Cache

一級快取包括8K位元組的指令快取和8K位元組的資料快取。二級快取有多種規格,主頻在150/166/180MHz的處理器使用256KB的二級快取,主頻在200MHz的處理器搭配有3種規格的快取:256K位元組,512K位元組和1M位元組,以當時的價格來看,非常昂貴。

一級快取執行頻率與CPU頻率相同,訪問一級快取通過CPU內部匯流排完成。

一級指令快取是8K位元組大小的4路組相聯快取記憶體;一級資料快取

是8K位元組2路組相聯快取記憶體,支援雙埠操作,可以在單個時鐘週期內一次存操作和一次取操作。指令快取只有取操作。一級快取的快取行大小都是32位元組。

 

匯流排介面單元通過外部系統匯流排訪問系統記憶體。外部匯流排是64位的事務型匯流排,也就是說每一次匯流排訪問都是由一對兒獨立的請求操作和響應操作完成。匯流排介面單元在等待某個請求的響應時,還可以發射數個額外的請求操作。

匯流排介面單元通過64位寬的快取記憶體匯流排訪問緊耦合的二級快取(這裡緊耦合指的是二級快取位於CPU晶片上,且與CPU工作在同頻率上)。快取記憶體匯流排也是事務型匯流排,支援最多4個併發的快取訪問。

 

Cache Consistency Protocol (MESI)

快取記憶體與系統記憶體的資料一致性由MESI快取一致性協議來保障。MESI代表快取記憶體中某個快取行可能的四種狀態,分別是:修改過modified,獨有exclusive,共享share和無效invalid。無論是單CPU還是多CPU系統,MESI協議都可以保證快取一致性,也可以用於檢測由自修改程式碼導致的一致性問題。TODO:解釋自修改程式碼

來自處理器執行單元的記憶體訪問請求將會經過記憶體介面單元和記憶體訪問排序緩衝區。這兩個單元用來支援在快取和系統記憶體各級之間流暢地訪問資料以避免記憶體訪問阻塞。在一級快取未中的情況下,一級快取會自動地將請求轉發到二級快取,如果還未中,匯流排介面單元會繼續將請求轉發到系統記憶體。

到二級快取和系統記憶體的請求會經過記憶體訪問排序緩衝區。該緩衝區類似於一個排程/分發站,它會跟蹤所有的記憶體請求,必要的情況下會重排序某些請求以避免訪問阻塞,提高吞吐量。例如,該緩衝區允許先做讀操作,再做存操作;也可能做一些預測式地“投機”讀操作;但是所有存操作都是按順序完成,而且從來不會做預測式地“投機”存操作。

Fetch/Decode Unit

取指單元從一級指令快取中讀取IA指令流,譯碼單元將其翻譯為微指令序列,也稱為uop序列或者uop流。這個uop流依然保持著最初程式設計時的指令順序被髮送到微指令池中。

取指單元每個時鐘週期從指令快取中讀取32位元組的指令流,標示出該指令流中每條IA指令的邊界,最後將按16位元組對齊的位元組流傳送到譯碼器。參看下圖,在第一個時鐘週期內,指令1和指令2會被髮送到指令譯碼器;但是指令3不會,因為指令3跨越了16位元組邊界,指令3(和後續的指令)將會在下一個週期送到譯碼器.

取指單元會綜合下列情況計算指令指標的值,指令指標確定了下一條要執行的指令。

  • 來自分支目標快取區的輸入
  • 異常/中斷的狀態
  • 來自整型執行單元的分支預測失敗

計算過程中最重要的部分是分支目標快取區提供的分支預測資訊。 使用了擴充套件的Yeh’s演算法,擁有512個條目的分支目標快取區可以提前檢查許多條指令。在這些指令中可能有許多的分支跳轉,過程呼叫,和返回指令,要想讓分發/執行單元更有效率的工作,就必須要準確地預測各種分支指令。

指令譯碼器包括三個獨立並行的譯碼器:2個簡單指令譯碼器和1個複雜指令譯碼器。一個譯碼器可以將一條IA指令轉換成一條或多條三運算元的微指令(每條微指令有一個邏輯目標運算元,兩個邏輯源運算元)。 微指令才是處理器中的6個並行執行單元執行的基本指令。換句話說,從Pentium Pro開始,處理器的執行單元不再執行IA指令,而是類RISC指令的微指令。Intel並沒有公佈微指令的指令集和細節,程式設計師要關心的依然是IA指令集。

許多IA指令可以由簡單譯碼器直接轉換成單條微指令,還有一些IA指令由複雜譯碼器轉換成1至4條微指令。更復雜的IA指令只能由微指令序列器譯碼成預程式設計的微指令序列(the more complex Intel Architecture instructions are decoded into sequences of preprogrammed micro-ops obtained from the microcode instruction sequencer)。

The MS ROM is used for CISC instructions not fully decoded by the default decoders (like repeat move strings), or by microcode assists used to address some modes of operation (like in Floating-Point assists).

 

指令譯碼器也會處理指令字首和迴圈操作。所有的譯碼器可以在單個時鐘週期內轉換最多達6條微指令(兩個簡單譯碼器產生2條微指令;複雜譯碼器產生4條微指令)。

Intel架構的暫存器組數量太少,由於暫存器相互依賴可能導致資源僵死問題。為了解決這個問題,處理器提供了40個程式設計師不可見的內部通用暫存器用來執行真正的計算操作。這些暫存器可以儲存整型和浮點型值。為了分配這些內部暫存器,微指令從指令譯碼器送到暫存器別名表單元。在這裡,對邏輯IA暫存器的引用會被轉換成對內部物理暫存器的引用。

注:當有了暫存器別名(重新命名)機制後,IA暫存器已經無需參與實際計算,所以稱為邏輯暫存器;真正參與計算操作的內部暫存器被稱為物理暫存器。

譯碼階段的最後一步是由暫存器別名表單元的分配器給微指令加上狀態位和標誌位,自此這些微指令即將可以被送入指令池進行亂序執行。

Instruction Pool (Reorder Buffer)

在進入微指令池(以前也被稱為微指令重排序快取區)之前,微指令的順序是嚴格按照IA架構程式設計時的順序排列的,沒有經過任何的重排序。

微指令池是一個可以按內容查詢的陣列記憶體區,被分配進了40個微指令暫存器。它儲存著即將被執行的微指令,以及已經執行過但是還未提交的微指令。這裡“提交”指的是微指令已經執行完畢,執行結果被寫回到指令指定的IA暫存器中,即程式設計師可見的機器狀態。分發/執行單元可以按任何順序從微指令池中提取微指令執行。

Dispatch/Execute Unit

分發單元和執行單元是亂序執行單元,根據微指令運算元的依賴關係和執行單元資源的可用情況,排程和執行儲存在微指令池中的微指令以及臨時儲存預測式投機執行的微指令的執行結果。

從指令池中排程和分發微指令的操作由微指令執行資源分配站完成,它持續地掃描微指令池,查詢到可以執行的微指令(即源運算元都已經可用),將其分發到可用的執行單元。微指令的執行結果會被送回指令池,與對應的微指令儲存在一起直到該微指令終了。排程和分發過程使用經典的亂序執行策略,微指令嚴格按照資料流的約束關係和執行資源的可用性被分發到執行單元中執行,不再考慮原始程式設計時的指令順序。當兩條或多條同類型的微指令(例如,整型操作)同時可以執行時,他們按照一個偽先入先出的佇列順序執行。

微指令的執行單元包括2個整型單元,2個浮點單元,和1個記憶體介面單元,使得每個時鐘週期內同時可以執行最多可達5條微指令(注意是微指令,不是IA指令)。

2個整型單元可以並行的執行整型兩條微指令。其中有一個整型單元還可以處理分支微指令,這個單元可以偵測到分支指令預測失敗,然後通知分支目標快取區BTB重啟指令流水線(重啟意味著效能損失)。下面是詳細的操作步驟。指令譯碼器會為每條分支微指令打上兩個分支目標地址(預測的跳轉目標地址和非跳轉地址)。當整型執行單元執行分支微指令時,它可以確定是否發生了跳轉(或者未跳轉順序執行)。如果發生了跳轉,則預測式“投機”執行的那些微指令將會被標記為可用,執行流會沿著預測的指令路徑繼續執行;如果沒有發生跳轉,整型單元中的跳轉執行單元會更該這些微指令的狀態,以便將他們從微指令池中刪除,然後給分支目標快取區BTB提供正確的跳轉地址,隨後BTB將會從新地址重啟流水線。

記憶體介面單元負責處理載入load和儲存store微指令。載入操作只需要指定記憶體地址,所以可以編碼在1條微指令中。儲存操作需要同時指定要寫入的記憶體地址和資料,所以需要編碼成2條微指令。記憶體介面單元中的儲存操作部分有兩個埠,可以並行的處理地址和資料。因此,記憶體介面單元可以在1個時鐘週期內同時執行1個載入和1個儲存操作。

浮點執行單元與Pentium處理器中的浮點單元類似,只是增加了數條新的浮點指令以便於將條件分支和move指令流水線化。

Retirement Unit

簡單的說,終了單元按照一定的條件將微指令的執行結果回寫到程式設計師可見的IA暫存器中,然後將微指令從微指令池中刪除。但是還有些細節要考慮,就如微指令執行資源分配站reservation station,終了單元持續的掃描微指令池,找到那些已經執行過的微指令,而且這些微指令也不再被其他的微指令依賴。對於這些微指令,同時會考慮到中斷,異常,斷點以及分支預測失敗等情形後,終了單元才會對其執行終了操作:嚴格按照程式設計順序回寫結果後刪除微指令。

每個時鐘週期,終了單元可以處理完成3條微指令。對每條微指令,終了單元會將執行結果提交(即回寫)到IA暫存器堆或/和記憶體中,然後將其從微指令池中刪除。這裡IA暫存器堆包括8個通用暫存器,8個浮點資料暫存器。