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 的簡寫。