第4章 指令系統結構
第三題 條件轉移指令
3.假定在指令系統設計中需要考慮兩種條件轉移指令的設計方法,這兩種方法如下。
(1)CPU A:先透過一條比較指令設定條件碼A,再用一條分支指令檢測條件碼。
(2)CPU B:比較操作包含在分支指令中。
在兩種CPU中,條件轉移指令都需要兩個時鐘週期,所有其他指令都需要一個時鐘週期。在CPU A中,全部指令的25%是條件轉移指令,因為每次條件轉移都需要一次比較,所以比較指令約佔所有指令的25%。因為CPU A不需要在轉移中包含分支,所以它的時脈頻率是CPU B的1.2倍。請問哪一種CPU效能更高?如果CPU A的時脈頻率只是CPU B的1.1倍,結果又是多少?
提示
題目問的是效能,可以預設問的是執行該程式(滿足25%是條件轉移)的效能。最終以實際執行的時間為標準;想計算時間,需要先計算總指令數量,才能算出所需時間。
題目分析:
兩種 CPU 比較效能:
- CPU A:條件轉移需要兩條指令(比較 + 分支)。
- CPU B:條件轉移透過一條指令完成。
條件:
- 條件轉移指令佔 25%,CPU A 的比較指令也佔 25%。
- CPU A 的時脈頻率是 CPU B 的 1.2 倍(第一問)或 1.1 倍(第二問)。
解答
-
計算總週期數
假設總指令數為 \(x\):- CPU A:總週期數: \(2 \times 0.25x + 1 \times 0.25x + 1 \times 0.5x = 1.25x\)
- CPU B:總週期數: \(2 \times 0.25x + 1 \times 0.75x = 1x\)
-
計算效能比
效能比公式:\[\text{效能比} = \frac{\text{CPU A 時脈頻率}}{\text{CPU B 時脈頻率}} \times \frac{\text{CPU B 週期數}}{\text{CPU A 週期數}} \]- 第一問:\(f_A / f_B = 1.2\)\[\text{效能比} = 1.2 \times \frac{1}{1.25} = 0.96 \]第二問:\(f_A / f_B = 1.1\)\[\text{效能比} = 1.1 \times \frac{1}{1.25} = 0.88 \]
- 第一問:\(f_A / f_B = 1.2\)
答案
- 當 CPU A 時脈頻率為 CPU B 的 1.2 倍時,效能比為 96%。
- 當 CPU A 時脈頻率為 CPU B 的 1.1 倍時,效能比為 88%。
結論: CPU A 效能在兩種情況下都低於 CPU B。
第5章 靜態流水線
第二題 時空圖 MIPS程式
2.對於下面的計算:
A=A+B
C=A-B
寫出MIPS程式程式碼,並且畫出5級靜態流水線(無旁路)的流水線時空圖。
題目分析
MIPS 程式碼實現計算:
A = A + B
C = A - B
假設:
- 流水線無旁路(No forwarding)。
- 資料依賴會導致流水線阻塞。
- 需要繪製 5 級靜態流水線的時空圖(IF, ID, EX, MEM, WB)。
MIPS 程式程式碼
按照操作順序,MIPS 彙編程式碼如下:
LW R1, 0(R0) # Load A into R1 (A = Memory[0(R0)])
LW R2, 4(R0) # Load B into R2 (B = Memory[4(R0)])
ADD R3, R1, R2 # R3 = A + B
SUB R4, R3, R2 # R4 = (A + B) - B = A
SW R3, 0(R0) # Store R3 (A + B) back to Memory[0(R0)]
SW R4, 8(R0) # Store R4 (A) to Memory[8(R0)]
靜態流水線的特點
- 無旁路時的流水線阻塞:
- 在無旁路的情況下,如果後續指令依賴於前一指令的執行結果,必須等待前一指令完成寫回階段(WB)後才能繼續執行。
- 流水線執行順序:
- 每條指令需要經過 IF → ID → EX → MEM → WB\text{IF → ID → EX → MEM → WB} 五個階段。
時空圖分析
- LW R1, 0(R0):
- 完整流水線階段:IF → ID → EX → MEM → WB。
- LW R2, 4(R0):
- 不存在資料依賴,可以連續進入流水線。
- ADD R3, R1, R2:
- 存在資料依賴,需要等待
LW R1
和LW R2
完成寫回(WB),才能進入流水線。
- 存在資料依賴,需要等待
- SUB R4, R3, R2:
- 同樣存在資料依賴,需要等待
ADD
完成寫回(WB)。
- 同樣存在資料依賴,需要等待
- SW R3, 0(R0):
- 無資料依賴,可以直接進入流水線。
- SW R4, 8(R0):
- 依賴於
SUB
的結果,需要等待寫回完成。
- 依賴於
時空圖:
以下是流水線各指令的執行階段:
答案總結
-
MIPS 彙編程式碼:
LW R1, 0(R0) LW R2, 4(R0) ADD R3, R1, R2 SUB R4, R3, R2 SW R3, 0(R0) SW R4, 8(R0)
-
時空圖:
- LW 指令 無資料依賴,直接進入流水線。
- ADD/SUB 指令 等待前置指令寫回後才能執行,產生流水線阻塞。
- SW 指令 需要等待運算元寫回完成。
-
流水線阻塞原因:
- 無旁路機制導致後續指令必須等待前一指令的結果寫回(WB)後才能繼續。
透過時空圖可見,執行該段程式碼共需 18 個時鐘週期。
第6章 動態流水線
第五題 浮點流水線
5.以下這個迴圈是高斯消元法中的核心操作,稱為DAXPY迴圈(雙精度的a乘以X 再加上Y),以下程式碼實現了對長度為100的向量進行DAXPY操作:Y=a*X+Y。
bar:
LDC1 F2, 0(R1) ; 取數 X(i)
MUL.D F4, F2, F0 ; 乘法操作 a * X(i)
LDC1 F6, 0(R2) ; 取數 Y(i)
ADD.D F6, F4, F6 ; 加法操作 a * X(i) + Y(i)
SDC1 F6, 0(R2) ; 存數 Y(i)
DADDIU R1, R1, #8 ; X 的下標加 1
DADDIU R2, R2, #8 ; Y 的下標加 1
DSGTUI R3, R1, #800 ; 測試迴圈是否結束
BEQZ R3, bar ; 如果迴圈沒有結束,轉移到 bar
NOP ; 空指令
在單發射靜態流水線上,假定浮點流水線的延遲如附表6.1所示(延遲為N表示第T 拍運算元準備好開始運算,第 \(T+N-1\) 拍可以寫回結果),分支指令在譯碼階段(ID)計算結果,採用了分支延遲槽技術,整數操作在一拍之內發射和完成,並且結果是完全旁路的(fully bypassed)。
附表6.1 浮點流水線的延遲 | ||
---|---|---|
產生結果的指令 | 使用結果的指令 | 延遲(時鐘週期) |
FP ALU op | Another FP ALU op | 4 |
FP ALU op | Store double | 3 |
Load double | FP ALU op | 2 |
Load double | Store double | 1 |
(1)把這個迴圈展開足夠的次數,要求消除所有停頓週期和迴圈開銷指令。迴圈將會被展開多少次?寫出排程後的程式碼,每產生一個結果需要多少執行時間?
(2)寫出DAXPY迴圈在軟體流水後的程式碼,可以省略軟體流水的裝入程式碼和排空程式碼,每產生一個結果需要多少執行時間?
題目分析
該問題圍繞 DAXPY 迴圈 \(Y = a \cdot X + Y\) 的最佳化,要求透過 迴圈展開 和 軟體流水 方法最佳化指令執行,減少停頓週期和迴圈開銷,提升流水線效率。
透過 迴圈展開兩次,可以減少資料依賴導致的流水線阻塞問題。每次迴圈處理 2 個元素,並透過指令排程最佳化流水線的利用率。
解答:
(1)迴圈展開兩次,每產生一個結果需要7拍執行時間
程式碼:
bar:
L.D F2, 0(R1) ; Load X(i)
L.D F3, 8(R1) ; Load X(i+1)
L.D F6, 0(R2) ; Load Y(i)
MUL.D F4, F2, F0 ; a * X(i)
MUL.D F5, F3, F0 ; a * X(i+1)
L.D F7, 8(R2) ; Load Y(i+1)
DADDIU R1, R1, #16 ; X 下標加 2
ADD.D F6, F4, F6 ; a * X(i) + Y(i)
ADD.D F7, F5, F7 ; a * X(i+1) + Y(i+1)
DADDIU R2, R2, #16 ; Y 下標加 2
S.D F6, -16(R2) ; Store Y(i)
DSGTUI R3, R1, #800 ; 檢測是否結束
BEQZ R3, bar ; 迴圈跳轉
S.D F7, -8(R2) ; Store Y(i+1)
執行時間分析:
- 每次迴圈執行時間:14 個週期,處理 2 個元素。
- 每個元素的平均執行時間: \(\frac{14}{2} = 7 \, \text{拍/元素}\)
(2)迴圈展開兩次,每產生一個結果需要9拍執行時間,9拍處理1個元素。
以下是按照軟體流水最佳化後的程式碼與分析:
軟體流水後的程式碼
bar:
S.D -24(R2), F6 ; 第 i-3 次迴圈的儲存操作
ADD.D F6, F4, F8 ; 第 i-2 次迴圈的加法操作
MUL.D F4, F2, F0 ; 第 i-1 次迴圈的乘法操作
L.D F2, 0(R1) ; 第 i 次迴圈的裝入 X(i)
L.D F8, -8(R2) ; 第 i-1 次迴圈的裝入 Y(i-1)
DADDIU R1, R1, #8 ; X 下標加 1
DSGTUI R3, R1, #800 ; 測試迴圈是否結束
BEQZ R3, bar ; 跳回 bar
DADDIU R2, R2, #8 ; Y 下標加 1
最佳化分析
- 軟體流水特點:
- 將迴圈的計算部分分解為 儲存、加法、乘法 和 裝入,使不同迴圈的操作交錯執行。
- 每個操作在不同週期進行,形成“流水線式”並行處理。
- 執行時間:
- 每次迴圈需 9 個週期完成。
- 每個結果的平均執行時間為 9 個週期/結果。
- 裝入程式碼和排空程式碼:
- 省略裝入和排空階段的額外指令,直接開始處理迴圈資料。
結果總結
- 軟體流水的程式碼:見上方最佳化後的程式碼。
- 每個結果的執行時間:9 個週期。
- 最佳化效果:充分利用流水線隱藏資料依賴,每次迴圈計算與資料裝入和儲存操作重疊,提高了效率。
第六題 精確例外處理動態流水線
6.假設有一個如附圖6.1所示的支援精確例外處理的浮點流水線。流水線分成發射、執行並寫回以及提交3個階段,其中浮點加法部件延遲為2拍(即假設第T拍運算元準備好開始運算,第T十1拍可以寫回結果),浮點乘法部件延遲為3拍,浮點操作佇列中已有圖中所示的指令,且暫存器的初值如圖6.1所示,請給出6拍內每一拍的暫存器以及結果匯流排值的變化。
參考答案:
解析:
本題要求我們根據題目中的浮點流水線結構和指令狀態,分析 6 拍內暫存器和結果匯流排的變化情況。以下是對每一拍的詳細解析。
基礎資訊
- 浮點部件延遲:
- 加法操作部件延遲為 2 拍。
- 乘法操作部件延遲為 3 拍。
- 暫存器初值:
- 如圖中所示,暫存器 F0, F1, F2, F3 分別為 1.0, 2.0, 3.0, 4.0。
- 指令佇列:
- DIV.D F0, F1, F2:除法。
- MUL.D F3, F0, F2:乘法。
- ADD.D F0, F1, F2:加法。
- MUL.D F3, F0, F2:乘法。
- 操作階段:
- 發射 (Issue)、執行 (Execute)、寫回 (Writeback)、提交 (Commit)。
逐拍解析
Cycle 1:
- 暫存器狀態:
- F0 = 1.0, F1 = 2.0, F2 = 3.0, F3 = 4.0。
- 結果匯流排 (Resbus):無寫回。
- 操作:
- DIV.D F0, F1, F2:進入執行階段,使用除法部件。
- 結果尚未寫回。
Cycle 2:
- 暫存器狀態:
- F0 = 1.0, F1 = 2.0, F2 = 3.0, F3 = 4.0。
- 結果匯流排:
- \(\text{DIV.D F0 = 1.0 / 3.0 = 0.67}\),準備寫回。
- 操作:
- MUL.D F3, F0, F2:進入執行階段,使用乘法部件。
- DIV.D 結果準備寫回。
Cycle 3:
- 暫存器狀態:
- F0 = 0.67, F1 = 2.0, F2 = 3.0, F3 = 4.0。
- 結果匯流排:
- \(\text{MUL.D F3 = 0.67 × 3.0 = 2.0}\),尚未寫回。
- 操作:
- ADD.D F0, F1, F2:進入執行階段,使用加法部件。
- MUL.D 結果等待寫回。
Cycle 4:
- 暫存器狀態:
- F0 = 0.67, F1 = 2.0, F2 = 3.0, F3 = 2.0。
- 結果匯流排:
- \(\text{ADD.D F0 = 2.0 + 3.0 = 5.0}\),尚未寫回。
- 操作:
- MUL.D F3, F0, F2:進入執行階段,使用乘法部件。
- ADD.D 結果等待寫回。
Cycle 5:
- 暫存器狀態:
- F0 = 5.0, F1 = 2.0, F2 = 3.0, F3 = 2.0。
- 結果匯流排:
- \(\text{MUL.D F3 = 5.0 × 3.0 = 15.0}\),準備寫回。
- 操作:
- 繼續完成 MUL.D 的寫回。
Cycle 6:
- 暫存器狀態:
- F0 = 5.0, F1 = 2.0, F2 = 3.0, F3 = 15.0。
- 結果匯流排:
- 無剩餘操作,所有指令已完成寫回。
總結
- 關鍵時間點:
- \(\text{DIV.D F0}\) 在 Cycle 2 寫回。
- \(\text{MUL.D F3}\) 在 Cycle 5 寫回。
- \(\text{ADD.D F0}\) 在 Cycle 4 寫回。
- 最後一條 \(\text{MUL.D F3}\) 在 Cycle 6 寫回。
透過軟體流水線設計與暫存器結果表的跟蹤,實現了支援精確例外的浮點操作。
第7章 多發射資料通路
第四題 流水線延遲元素執行時間
4.假設流水線延遲如附表7.1所示,分支延遲為1個週期,沒有延遲槽。
附表7.1 流水線延遲 | ||
---|---|---|
產生結果的指令 | 使用結果的指令 | 延遲(時鐘週期) |
FP ALU op | Another FP ALU op | 4 |
FP ALU op | Store double | 3 |
Load double | FP ALU op | 2 |
Load double | Store double | 1 |
下面迴圈計算\(Y[i]=a*X[i]+Y[i]\)高斯消元法中的關鍵一步。
L: LDC1 F4, 0(R2) ; 讀 Y[i]
LDC1 F0, 0(R1) ; 讀 X[i]
MUL.D F0, F0, F2 ; 求 a * X[i]
ADD.D F0, F0, F4 ; 求 a * X[i] + Y[i]
SDC1 F0, 0(R2) ; 儲存 Y[i]
DADDIU R2, R2, -8 ; 更新 R2
DADDIU R1, R1, -8 ; 更新 R1
BNEZ R1, L ; 如果 R1 不為零,跳轉到 L
NOP ; 空指令
(1)假設目標機器的流水線是單發射的,將次迴圈展開足夠的次數,使得程式碼執行沒有不必要的延遲,寫出排程後的程式碼並計算一個元素的執行時間。
(2)假設目標機器的流水線是雙發射的,將次迴圈展開足夠的次數,使得程式碼執行沒有不必要的延遲,寫出排程後的程式碼並計算一個元素的執行時間。
(3)自己寫一段與題中類似的C程式碼,用gcc的不同最佳化編譯選項編譯後,檢視彙編程式碼,對不同最佳化選項進行比較,描述gcc做的最佳化。
參考答案:
4.解:
注意沒有延遲槽,注意指令的延遲。(延遲的定義參見6章5題)
(1) 迴圈展開2次
L: L.D F0, 0(R1) ; load X[i]
L.D F6, -8(R1) ; load X[i-1]
MUL.D F0, F0, F2 ; a * X[i]
MUL.D F6, F6, F2 ; a * X[i-1]
L.D F4, 0(R2) ; load Y[i]
L.D F8, -8(R2) ; load Y[i-1]
ADD.D F0, F0, F4 ; a * X[i] + Y[i]
ADD.D F6, F6, F8 ; a * X[i-1] + Y[i-1]
DSUBUI R2, R2, 16 ; update R2
DSUBUI R1, R1, 16 ; update R1
S.D F0, 16(R2) ; store Y[i]
S.D F6, 8(R2) ; store Y[i-1]
BNEZ R1, L ; branch if R1 != 0
計算一個元素需14/2=7拍
正常展開即可.
(2)假設雙發射流水線中有彼此獨立的一條定點流水線和一個浮點流水線。
定點指令線:
L: L.D F0, 0(R1)
L.D F6, -8(R1)
L.D F10, -16(R1)
L.D F14, -24(R1)
L.D F4, 0(R2)
L.D F8, -8(R2)
L.D F12, -16(R2)
L.D F16, -24(R2)
DSUBUI R2, R2, 32
DSUBUI R1, R1, 32
S.D F0, 32(R2)
S.D F6, 24(R2)
S.D F10, 16(R2)
BNEZ R1, L
浮點指令線:
MUL.D F0, F0, F2
MUL.D F6, F6, F2
MUL.D F10, F10, F2
MUL.D F14, F14, F2
ADD.D F0, F0, F4
ADD.D F6, F6, F8
ADD.D F10, F10, F12
ADD.D F14, F14, F16
計算每個元素需要16/4=4拍
參考答案假設是直接按定點一條浮點一條來做。
(3) 實驗題。
int main()
{
// initialize the X[i] and Y[i];
int i;
for (i = 100; i >= 0; i--)
Y[i] = a * X[i] + Y[i];
return 0;
}
gcc -O
不進行最佳化,-O1, -O2
進行部分最佳化,但是不進行迴圈展開最佳化;-O3
進行所有的最佳化,包括迴圈展開,對該程式非常有效。
解析:
(1) 單發射流水線
-
目標:消除流水線延遲,保證指令間不會因資料相關而停頓。
-
方法:迴圈展開 2 次,使載入、計算和儲存的操作彼此交錯,儘量減少流水線延遲。
-
程式碼解釋
:
- 讀取
X[i]
和X[i-1]
,並計算a*X[i]
和a*X[i-1]
。 - 讀取
Y[i]
和Y[i-1]
,再進行加法。 - 更新指標
R1
和R2
,分別指向下一批元素。 - 儲存計算結果。
- 迴圈檢查
R1
是否為 0。
- 讀取
-
執行時間:迴圈展開 2 次後,每 2 個元素需要 14 個時鐘週期,因此每個元素需要 7 個時鐘週期。
(2) 雙發射流水線
-
目標:利用雙發射能力,同時執行一條定點指令和一條浮點指令,提高並行度。
-
方法:迴圈展開 4 次,並將定點操作和浮點操作分開排程。
-
程式碼解釋
:
- 在定點流水線上,讀取
X[i]
系列和Y[i]
系列的資料,並更新指標。 - 在浮點流水線上,進行乘法和加法運算。
- 資料儲存與定點流水線和浮點流水線相輔相成,無阻塞。
- 在定點流水線上,讀取
-
執行時間:每 4 個元素需要 16 個時鐘週期,因此每個元素需要 4 個時鐘週期。
(3) 實驗題 (C語言程式碼)
- 程式碼功能:計算
Y[i] = a*X[i] + Y[i]
。 - 最佳化選項:
-O
:不最佳化,保留原始指令順序。-O1, -O2
:進行部分最佳化,例如指令排程、常量摺疊等,但不進行迴圈展開。-O3
:執行所有最佳化,包括迴圈展開、指令合併、暫存器分配最佳化等。
- 效果:
-O3
最佳化顯著減少了迴圈的指令開銷,透過迴圈展開、流水線最佳化等大幅提升了執行效率。
總結:
- 單發射流水線:迴圈展開 2 次,達到無延遲執行,每個元素需要 7 個時鐘週期。
- 雙發射流水線:迴圈展開 4 次,充分利用並行能力,每個元素需要 4 個時鐘週期。
- C程式碼最佳化:
-O3
編譯最佳化尤其適合該程式,可顯著提升執行效率,建議實際應用中使用高階最佳化選項。
第五題 物理暫存器個數需求
5. 一個 \(n\) 發射的處理器,流水線情況如下:取指、譯碼、重新命名到物理暫存器後送入發射佇列,發射佇列亂序發射,功能部件亂序執行,亂序寫回物理暫存器,最後順序提交併釋放物理暫存器。已知該處理器有 \(m\) 個邏輯暫存器,i 個功能部件\((i > n)\),每條指令從重新命名到寫回需要 \(t_1\) 拍,從重新命名到提交交需要 \(t_2\) 拍。為了能讓流水線滿負荷工作,最少需要多少個物理暫存器?(提示:並不是每個引數都有用)
參考答案:
物理暫存器個數應至少為 \(n \times t_2 + m\) 才能讓流水線滿負荷工作。
每條指令在重新命名的時候需要佔用一個物理暫存器,每拍 \(n\) 條指令發射,則需要佔用 \(n\) 個物理暫存器。被重新命名的物理暫存器只有在提交的時候,並且不是當前邏輯暫存器的時候,才被釋放。從重新命名到提交共計有 \(t_2\) 拍,當流水線滿負荷工作,流水線佔用了 \(n \times t_2\) 個物理暫存器,另外邏輯暫存器數目為 \(m\) 個,因此共需要物理暫存器的個數為 \(n \times t_2 + m\)。
簡要解析:
為了讓流水線滿負荷工作,物理暫存器數量需要滿足兩個條件:
- 發射到提交的暫存器佔用:
每拍發射 \(n\) 條指令,從重新命名到提交共需 \(t_2\) 拍,因此流水線同時需要保留 \(n \times t_2\) 個物理暫存器用於指令佔用。 - 邏輯暫存器需求:
系統中存在 \(m\) 個邏輯暫存器,每個邏輯暫存器都需要一個物理暫存器對映。
因此,總的物理暫存器需求為:\(n \times t_2 + m\)
關鍵點:
- 重新命名階段:每條指令分配一個物理暫存器。
- 釋放條件:物理暫存器只有在提交後,且不再被當前邏輯暫存器使用時,才會釋放。
- 滿負荷流水線:確保所有 \(n\) 條指令從發射到提交的整個過程中,始終有足夠的物理暫存器支援指令執行。
參考文獻
[1] 國科大胡偉武老師計算機體系結構課後答案(最新版) from CSDN.
[2] 計算機體系結構 第二版 胡偉武 清華大學出版社