1. 轉(zhuǎn)移指令對流水線的影響
如下圖所示,T1周期取指add指令,T2周期取指sub指令,T3周期取指beq指令。

對于人類來說,我們能看到sub和beq之間可能存在一個循環(huán),但是計算機(jī)不知道,它只會在繼續(xù)取指,T4周期取指lw指令,此時beq指令完成譯碼階段但是還不知道要不要跳轉(zhuǎn)。因此T5繼續(xù)取指sw指令,T5結(jié)束時,beq完成執(zhí)行階段,此時知道了是否跳轉(zhuǎn)。
如果beq條件滿足,即s3 == s4,那么就要跳轉(zhuǎn)到Next執(zhí)行,lw指令和sw指令實際上就不應(yīng)該被執(zhí)行,如下圖所示,

那么T6周期取指sub指令,T7周期取指beq指令,后面又和T4、T5一樣了。總體看來就是處理器取回2條正確指令,接著取回2條錯誤指令(假設(shè)beq條件滿足),如此反復(fù),流水線的50%性能被浪費(fèi)了。這是因為轉(zhuǎn)移指令本身和流水線的要求是相違背的。轉(zhuǎn)移指令改變指令流向,破壞了流水模式。
2. 轉(zhuǎn)移指令對性能的影響
如下圖所示,轉(zhuǎn)移指令在程序中的占比挺大,因此不能忍受其對流水線的破壞,必須解決,

如下圖所示,當(dāng)前流行的處理器超標(biāo)量數(shù)多、流水線級數(shù)深,轉(zhuǎn)移指令如果不解決,對處理器的流水線影響太大!

3. 轉(zhuǎn)移開銷
如下圖所示,對于轉(zhuǎn)移指令,必須解決兩個問題,一個是轉(zhuǎn)移判定條件,一個是生成目標(biāo)地址。

4. 轉(zhuǎn)移指令的分類
從2個維度分為4類,如下圖所示,直接轉(zhuǎn)移指令是把目標(biāo)地址直接寫在指令編碼中,而間接轉(zhuǎn)移指令的目標(biāo)地址放在一個寄存器中,指令需要先訪問這個寄存器才可以知道目標(biāo)地址,

5. 無條件轉(zhuǎn)移指令
5.1 直接轉(zhuǎn)移 j Target
如下圖所示,因為是無條件轉(zhuǎn)移指令,因此不需要判斷是否轉(zhuǎn)移。

指令編碼中就有26-bit立即數(shù),根據(jù)計算公式就可以計算出轉(zhuǎn)移目標(biāo)地址。
根據(jù)計算公式,可以看出目標(biāo)地址只與當(dāng)前PC寄存器的值和指令編碼中的26-bit立即數(shù)有關(guān)。從數(shù)據(jù)通路上來看,如下圖所示,

指令存儲器根據(jù)PC的值就可以取出指令,在這個取指階段,加一些硬件電路就可以判斷出這是一條無條件直接轉(zhuǎn)移指令,然后PC update部件就是PC+4的值,將這個PC update部件的輸出的高4位和指令中的26-bit立即數(shù)再和00拼起來,就是轉(zhuǎn)移目標(biāo)地址了。流水線不需要stall。
5.2 無條件間接轉(zhuǎn)移指令 jr rs
如下圖所示,無條件間接轉(zhuǎn)移指令 jr rs,從寄存器堆中讀取rs指定的寄存器的內(nèi)容,將這個數(shù)據(jù)作為轉(zhuǎn)移目標(biāo)地址。

從處理器結(jié)構(gòu)上,來看如何處理無條件間接轉(zhuǎn)移指令,如下圖所示,

在取指階段無法確定轉(zhuǎn)移目標(biāo)地址,因此流水線必須stall一個周期,在譯碼階段,busA上的數(shù)據(jù)就是rs指定的寄存器的數(shù)據(jù),利用這個數(shù)據(jù)就可以計算出轉(zhuǎn)移目標(biāo)地址。因此,對于無條件間接轉(zhuǎn)移指令,流水線必須stall一個周期。
6. 條件轉(zhuǎn)移指令
如下圖所示,beq指令是條件直接轉(zhuǎn)移指令,判斷如果R[rs] == R[rt]后,目標(biāo)轉(zhuǎn)移地址的計算就如下圖所示,否則不滿足條件,PC的更新就是PC+4.?

我們發(fā)現(xiàn),不論條件是否滿足,目標(biāo)轉(zhuǎn)移地址都只與當(dāng)前PC寄存器的值和指令編碼中的立即數(shù)有關(guān),因此目標(biāo)地址的計算不會stall流水線。
而條件的判斷會影響流水線。如下圖所示,在譯碼階段完成時,rs和rt指定的寄存器的數(shù)據(jù)輸出在busA上和busB上,但此時還無法判斷兩個寄存器的數(shù)據(jù)是否相等。在執(zhí)行階段完成時,ALU輸出就可以判斷兩個寄存器是否相等了,因此流水線需要stall兩個周期。

但其實,判斷rs和rt指定的寄存器的數(shù)據(jù)是否相等很簡單,對寄存器堆做一點(diǎn)改造就可以在譯碼階段完成判斷。如下圖所示,這樣,流水線只需要stall一個周期,beq指令對流水線的影響降低了,

7. 控制冒險的影響總結(jié)
綜上,我們發(fā)現(xiàn),
無條件直接轉(zhuǎn)移指令 j Target 不會stall流水線
無條件間接轉(zhuǎn)移指令 jr rs 會stall一個周期
條件直接轉(zhuǎn)移指令 beq rs,rt,imm16 會stall一個周期
8. 進(jìn)一步優(yōu)化,不讓轉(zhuǎn)移指令影響流水線
8.1 延遲轉(zhuǎn)移技術(shù)
如下圖所示,xor指令,addi指令,subi指令后,跟著一條beq指令,beq指令stall流水線1個周期后,會判斷轉(zhuǎn)移還是不轉(zhuǎn)移,這里流水線就空出了一個周期,我們可以在這個周期中插入一條指令而不影響流水線。

那么就向上去找,addi指令和subi指令都與beq指令依賴,但是xor指令與beq指令沒有依賴,就可以調(diào)整指令順序,將xor指令放在beq指令后面執(zhí)行,那么流水線就不需要stall了。如下圖所示,這樣beq指令取指后進(jìn)入譯碼階段,xor指令就可以進(jìn)入流水線取指,xor取指后,beq就完成了條件判斷,知道是否轉(zhuǎn)移了。這樣,流水線就不需要stall了。
