2011年2月10日 星期四

再提"雙發射"。

Shady 曾在「撰寫 Cell 的 PPU 之組語所需的知識及技巧。」此文章中提過 "雙發射",
當中有提到「這也是 "雙執行緒" 用來加強 IPC 的機制。」
這裡的 "雙執行緒" 打錯了,應該為 "單執行緒"。

現在來談談如何最佳化 "雙發射" 所該有的注意事項,
由於 PPU 的指令長度都是 32bits ( 4Bytes ),
且指令的預先提取為四個指令、解碼為二個指令同時解碼,
所以預先提取與指令解碼的指令之位址將會是連續的,
以下列程式為例:
    位址       標籤       指令
0x1000_04F0          vand 3,1,2
0x1000_04F4          beq .Lend
0x1000_04F8          add 5,6,7
0x1000_04FC          add 3,8,9
0x1000_0500  .Lend:  sub 4,5,6
0x1000_0504          ldu 10,16(7)
0x1000_0508          stvx 0,5,4
0x1000_050C          std 4,16(7)

從此例中可發現指令位址的尾數都是以 0、4、8、C 為循環,
而 IB (註1) 會提取前四行指令,
而第一、二行指令會先同時解碼,
在解碼的同時亦會檢查 "相依性" 與是否可以 "雙發射",
所以此例的 "雙發射" 結果為:
第一、二行指令可 "雙發射",原因為指令執行單元是 VSU1 與 BRU。
第三、四行指令不可 "雙發射",原因為指令執行單元是 FXU 與 FXU。
第五、六行指令不可 "雙發射",原因為指令執行單元是 FXU 與 LSU、FXU。
第七、八行指令可 "雙發射",原因為指令執行單元是 VSU2 與 LSU。

從結果可看出執行單元的不同就能 "雙發射",
要注意第七、八行的 VSU2 單元一定要在 LSU 之前,
如此順序才能讓 VSU2 與 LSU 達成 "雙發射"。

還有如 ldu、stdu 等指令會同時使用 LSU、FXU 等二個以上的執行單元,
有些指令甚至會使用到三個以上的執行單元。

如果在無相依的狀況下,
但執行單元卻是相同的話,
就會如第五、六行指令一樣不能 "雙發射",
而且第六行指令會在第五行指令的下個 CPU 週期發射。
若第五行指令的執行單元為 LSU 和 FXU 以外的執行單元,
這樣就能讓第五、六行達成 "雙發射" 之條件。
第三、四之行情形如同第五、六行之情形。

所以無相依性、不同單元可一個 CPU 週期發射二個指令,
而無相依性、相同單元只能二個 CPU 週期發射二個指令,
但有相依性、不論相不相同單元都會是二個以上 CPU 週期發射二個指令。

另外,分支指令最好放置在位址尾數為 0x4 和 0x8,
這樣能對分支預測及程式執行有益處。
然後分支目標最好座落於位址尾數為 0x0 和 0x8,
因為解碼都是 0x0 配 0x4,
而 0x8 配 0xC。

最後就是盡量不要使用會 stall 的指令、非管線化的指令和微碼指令,
因為它們會讓 "雙發射" 失效。
其餘該注意的事項之嚴重性都較以上小,
若有興趣者請多參考 IBM 所放出來的文件。

註1:Instruction Buffer 的簡寫。

沒有留言:

張貼留言