採用循序發射與執行方式的限制,意思就是,衣服只能一件一件洗,洗完一件才能洗下一件。如果現在洗衣機壞掉了(硬體故障),或者衣服還沒髒(運算元不可用),這個流水線就停頓了,哪怕後面還有指令等待執行。但是我們希望運算元可用的時候就立即執行指令(有髒衣服就洗),這樣的流水線實際上是亂序執行的,意味著它將會亂序完成。這就是動態排程的主要思想。
我們的目的是讓運算元可用的時候立即開始執行。於是我們增加了乙個「管家」,如圖所示:
tomasulo演算法大概是這樣的:
這家主人說我要洗衣服,告訴了管家,這個步驟叫做指令發射。之前不同的是,這個指令由管家儲存,並把相應的操作和衣服放在了新木桶中,這個木桶就是演算法中的保留站。這個木桶很大,可以存放多條指令。不像之前,必須一條一條指令循序執行。不過有一點要注意,在tomasulo演算法中,指令仍然是循序發射的。主人1,主人2跟管家說我要洗衣服,這個過程是乙個乙個來的。
但是動態排程是如何實現的呢?
現在新木桶很大,現在裡邊可以存放多條指令和衣服。但是現在管家發現了,雖然主人1說要洗一件衣服,但是衣服還沒來,或者是這件衣服還在洗衣機中洗。那麼管家就會在木桶中給主人1留乙個位置。因為衣服還沒來,沒辦法洗。這時候管家就會為主人2先洗衣服,同時監視晾衣架上主人1的衣服有沒有洗好。一旦發現晾衣架上主人1的衣服準備好了,那麼就立即開始為主人1洗衣服。這就實現了:
tomasulo演算法的真實結構圖如下所示:
下面講一下演算法的細節問題:
看以下下面這串**:
div.d f0,f2,f4 ;f0 = f2/f4
add.d f6,f0.f8 ;f6 = f0 + f8
s.d f6,0(r1) ;儲存
sub.d f8,f10.f8 ;f8 = f10 - f8
mul.d f6,f10,f8 ;f6 = f10 * f8
雖然**不大,但出現的資料冒險很多,共有5個:
把這個演算法寫到保留站時,保留站應該如何處理呢?
暫存器重新命名!
保留站會把這個**改寫一丟丟,對暫存器進行重新命名,使其不在衝突。改寫後的**如下:
div.d f0,f2,f4
add.d s,f0,f8
s.d s,0(r1)
sub.d t,f10,f14
mul.d f6,f10,t
s,t為重命名的暫存器名稱,這樣就去除了所有的讀後寫war冒險和寫後寫waw冒險。但是如果細心點會發現,改寫後的**中還存在寫後讀冒險。應該如何解決呢?因為剛才也介紹到,保留站只會在運算元可用的時候才會執行程式。如果正在寫源暫存器,那麼保留站將會先執行其他執行,等待源暫存器寫好,再執行此條指令,這樣就解決了所有的寫後讀raw冒險。總結來說:
另外,在寫結果時,先將計算結果寫到cdb(公共資料匯流排)中。然後cdb上進行廣播,看這個計算結果有沒有作為是其他指令源運算元的。如果保留站發現有,就會更新保留站源運算元的值。這樣就代替了流水線暫存器。
什麼是推測呢?舉個例子,現在這家主人說,我要洗衣服,我洗完這件還得洗,不過洗的衣服不確定,要麼洗衣服a,要麼洗衣服b,或者還有更多的選項。因為管家是提前處理指令的。所以現在他不知道要洗衣服a還是b。就沒辦發提前處理了。所以現在有兩種選擇:
1)等待,直到執行完分支指令,計算出分支位址之後,確定了要洗衣服a還是洗衣服b的時候再開始洗。這種就是無推測的執行方法,但是會產生不小的流水線停頓。
2)猜。洗衣服要麼是a要麼是b(如果只有兩分支的話),我猜要洗衣服a,就開始先洗了。這樣的提前處理,如果分支猜對了,就節省了很多的時鐘週期。但有個問題猜錯了話,咋辦?
猜錯了的話,首先,你得把衣服b還給人家吧。這種方式就是保持異常行為的一種。意思是:你現在程式執行錯誤,你必須要回到原來的狀態,以重新執行正確的程式。但是怎麼正確的處理**錯誤導致的異常呢?這裡增加了乙個概念叫:重排序緩衝區(rob)。它的主要思想是:
我們tomasulo演算法中實現重排序緩衝區,其思想就變成了
現在對於推測錯誤就很好處理了,因為哪怕已經執行了分支之後的命令,由於之前的指令還沒有執行完畢,分支之後的指令就無法提交,所以很容易的就程式計數器改為正確的分支位址,而不影響其他指令結果。
實際上,**錯誤的概率還是相對較低的,在intel core i7的分支**器中錯誤**率平均在5%以下。
體系結構學習筆記 白話理解Tomasulo演算法
單位時間執行的指令數目是衡量cpu的一項重要指標,為了讓各個部件盡量處於工作狀態,於是提出了指令流水,但是隨之而來的問題就是因為程式之間的相關性,從而引起的流水線堵塞,影響了流水線效能。為了進一步提高流水線效能,就提出了亂序執行,也就是部分程式不需按照原先的順序執行。可以試想,若有一指令執行時間非常...
EM演算法簡單理解
在求解概率模型的時候,如果需要的變數都是觀測變數,不涉及到隱藏變數的話,可以使用極大似然或者貝葉斯估計來求解模型的引數。比如 對於單高斯模型來講,如果知道觀測變數,那麼就可以使用極大似然或者最小均方誤差來估計高斯模型的均值和方差。如果模型同時包含觀察變數和隱藏變數的話,傳統的方法不能完成模型的估計,...
簡單理解viterbi演算法
viterbi演算法其實就是多步驟每步多選擇模型的最優選擇問題,其在每一步的所有選擇都儲存了前續所有步驟到當前步驟當前選擇的最小總代價 或者最大價值 以及當前代價的情況下前繼步驟的選擇。依次計算完所有步驟後,通過回溯的方法找到最優選擇路徑。符合這個模型的都可以用viterbi演算法解決。隱含的身體狀...