體系結構筆記------動态排程中的記分闆算法
-
- 動态排程
- 流水線劃分
-
- 相關沖突
-
- 結構沖突
- 資料沖突
- 記分闆控制
-
- 流出
- 讀數
- 執行
- 寫回
- 具體算法
-
- 大緻流程
- 局限
動态排程
在程式執行的過程中,由硬體來對代碼進行排程來減少由于相關導緻的停頓。
對于基本的流水線而言,一旦一條指令受阻,其之後的所有指令都會是以停頓,為了提高流水線的性能我們需要使其可以進行亂序執行。
流水線劃分
對于原先的五段流水線,即取指周期(IF)、譯碼與讀數周期(ID)、計算與執行周期(EX)、訪存與分支跳轉(MEM)、寫回周期(WB)。我們将譯碼與讀數周期分為兩個階段,也就是流出階段與讀操作書階段。
流出階段:指令譯碼,檢查是否存在結
構沖突。
讀操作數:等待資料沖突消失,然後讀操作數。
相關沖突
結構沖突
對于多條指令同時對于同一硬體資源提出請求時産生的沖突為結構沖突,主要是由于有限的硬體資源所導緻的。
資料沖突
RAW:目前指令需要使用前面指令的結果,是以需要前面指令先寫入結果之後目前的指令再讀,主要由于真資料相關導緻。
WAR:指令間讀操作在前,寫操作在後,這是為保證讀到的資料為未被修改的資料,是以必須保證先讀後寫,對指令的執行順序有嚴格要求。
WAW:指令間寫操作的順序,如果兩條指令同時有寫資料的操作并且其操作的目标對象為同相同的寄存器或者記憶體單元,則也要保證其運作的先後順序,保證最終寫入的資料是最後執行的指令的。
這裡注意一點就是對于讀操作數這個階段,記分闆算法處理的方式是等待沖突消失而不是處理沖突。
記分闆控制
記分闆控制分為四級:流出、讀數、執行、寫回。(注意不同階段消耗的時鐘周期數不同!)
流出
這一階段進行指令譯碼,檢查是否含有結構沖突,也就是檢查目前的指令要使用的硬體的使用狀況,之後是檢查資料冒險,如果不存在其他運作的指令與目前指令有相同的目的寄存器(WAW)就将指令流出(相應的功能單元更新其内部資料),如果存在結構沖突或者資料冒險就停頓等待沖突消失。(并沒有實際解決沖突)
讀數
如果之前運作的指令沒有要寫入源操作數,或者目前運作的功能單元沒有準備寫入包含操作數的寄存器時,則源操作數可用。當操作數可用時進行資料讀入,并準備運作。(動态的解決RAW)這樣指令可以不按執行順序的進入執行階段。
執行
執行運算,完成後進入寫回階段。
寫回
在寫回階段,會先進行WAR沖突的檢查,如果存在先讀後寫就進行停頓等到讀結束之後寫回。(還是等待的方式處理)
具體算法
記分闆中記錄着程式運作時的狀況,主要可以三個表來描述。
指令的運作過程:也就是上面的四個步驟。
功能部件的狀态:由以下字段描述
Busy:用于描述功能部件硬體資源的占用情況
Op:說明運作時所用的是哪一個功能部件
Fi:目标寄存器
Fj, Fk:源操作數或寄存器
Qj, Qk:是否有某個功能單元占用源寄存器Fj或Fk。
Rj, Rk:用于辨別源寄存器是否準備好。
寄存器的寫入狀态:如果有某個功能部件最終将結果寫入該寄存器就将該寄存器标注上這個功能部件,如果沒有就是空白。
大緻流程
首先是取指令然後到ID段,分為譯碼與讀數兩個部分,先檢查結構冒險(檢查該指令需要使用的運算器是否正在被占用,通過相應功能部件的Busy段可得),有就等待沒有就進行操作數的檢查也就是資料冒險的檢查(檢查目的寄存器是否被功能單元占用等待寫入,通過寄存器的寫入狀态FU表對應)。若無資料沖突則指令流出至讀取操作數段。這裡解決了相關的WAW沖突與結構沖突。流出指令後對于對應的FU表中就應有相應的辨別了。
讀取操作數階段會通過上面的Qj,Qk段與Rj,Rk字段來判斷是否有功能單元對源寄存器有寫入操作,防止RAW發生,如果有的話就會等待相關的沖突結束,也就是相關的功能部件将結果寫入後再讀操作數。讀取後就交由運算器處理。這樣對于運算器而言有些先流出的指令會因為操作數的讀取而後執行,實作了指令的亂序執行。
指令的執行就沒啥可說的了,不同的指令執行周期不同,等到指令執行結束通知版準備寫回。
在寫回段主要檢查是否含有(WAR),如果有就等待相應的指令讀數結束在進行寫回操作,将結果寫入寄存器中。
在圖中ADD完成了運作,但是Div中的F6卻就緒了,由于F0的RAW并未讀入操作數,這時ADD
的結果也不能寫入,必須等到相應的讀操作結束才能寫入。
局限
對于冒險的處理大多以等待來解決,效率低。
存在結構冒險,就暫停發射指令;
無法消除 WAR 和 WAW 兩種相關,僅通過暫停來處理。
并行性的使用僅在處理RAW 相關時使用來亂序執行減少停頓周期。