亂序執行的目的就是盡可能的防止分發停頓,比如真正的寫后讀相關時,流水線必須停頓。思路就是讓相關的指令離獨立的指令遠一點。
亂序執行的條件
-
需要在值的生產者和消費者之間建立通信,這里消費者指的是當前這條指令,生產者指的是在與這條指令相關的指令。
- 寄存器重命名:給每個值一個tag。
-
需要給指令提供緩沖區。
- 保留站。
-
指令需要持續監測值是否可用。
- 當這個值准備好了,就廣播自己的tag,消費者匹配tag,如果是自己用的,就知道這個值已經准備好了。
-
當全部的值都准備好,需要分發指令到對應的功能單元上去。
- 需要的全部值都准備好,分發指令,出保留站。
寄存器重命名
Tomasulo算法
歷史
由Robert Tomasulo發明了帶寄存器重命名的亂序執行,用於IBM 360/91的浮點運算單元,需要注意的是當時的IBM 360/91並不支持精確異常,所以我們現在所說的Tomasulo算法與當時的方法還是存在區別。最早商用是在因特爾奔騰Pro。
今天幾乎全部主流處理器使用的亂序執行算法都是Tomasulo算法的變種。
指令執行規模受限於指令窗口。
步驟
如果保留站在重命名之前可用,那么將指令和操作數(值+tag)插入保留站。
在保留站中,每條指令關注公共數據總線(CDB)上的數據的tag,看到自己用的tag,就獲取數據並保存在保留站,知道全部操作數可用,進行指令分發。
那么指令在功能單元中完成操作后,進行CDB仲裁,將打了tag的值送到CDB上,寄存器堆也連接CDB,如果寄存器的tag(標記了最近需要寫入寄存器的entry)與廣播的tag匹配,將廣播的值存入寄存器,並置有效位,同時回收重命名的tag。
下面是一些例子:
非精確異常的無轉發:
非精確異常的全轉發:
非精確異常的Tomasulo+全轉發:
具體實現借助了寄存器重命名表(寄存器別名表RAT),接下來我們手推一下Tomasulo的過程。
保留站
相關指令的“休息區”,直到數據准備好才出來。這就需要時刻監控保留站中每條指令使用的值,也就是說指令是按照數據流的順序分發的。與精確異常中的ROB之類的方法不同,這里的亂序指的是亂序分發,而精確異常中指的亂序,意思是亂序執行,但是順序分發,順序回收。
好處:容忍延遲(允許獨立指令在長時延操作時執行和完成),可以連續的取指譯碼。
可以看下面的例子:
亂序執行的概念小結
寄存器重命名消除了虛假的相關,建立了生產者和消費者的關系。
保留站使得流水線可以執行獨立的操作以保持流水。
標簽廣播是的指令之間能夠交互生產出的值。
喚醒和選擇保證了亂序執行的分發。
亂序執行實際上是構建了一個程序塊的數據流圖,而數據流受限於指令窗口(ROB),簡單來說就是在這部分代碼段上可以亂序執行,雖然是亂序執行,但是保證了ISA順序的要求,亂序執行僅僅被約束在微體系結構層面。