我的教授聲稱 LOOP 在 8086 上更快,因為只獲取一條指令而不是兩條指令,例如 in dec cx, jnz。所以我認為我們通過避免每次迭代的額外獲取和解碼來節省時間。
但在講座的早些時候,他還提到 LOOP 與 DEC、JNZ 在引擎蓋下做同樣的事情,我認為它的解碼也應該更復雜,所以速度差異應該有點平衡。那么,為什么 LOOP 指令更快呢?我瀏覽了這篇文章,那里的答案與比 8086 更現代的處理器有關,盡管其中一個答案(及其鏈接的頁面)確實指出在 8088(與 8086 密切相關)上,LOOP 更快。
后來教授用同樣的道理解釋了為什么rep字串操作可能比 LOOP 單獨的移動指令更快,但是由于我對前面的方法并不完全信服,所以我在這里問了這個問題。
uj5u.com熱心網友回復:
我認為它的解碼也應該更復雜
沒有理由說loop指令的解碼更復雜。這條指令必須做多件事,但解碼不是問題——它應該JMP像JMP.
保存一條指令的獲取和解碼可能是提高速度的原因,因為在執行時它們實際上是等效的。
uj5u.com熱心網友回復:
問題不是解碼,通常是在 8086 上獲取。
啟動兩個單獨的指令解碼操作可能比僅為一條loop指令獲取更多微碼更昂貴。我猜這就是下表中不包括代碼獲取瓶頸的數字的原因。
同樣或更重要的是,8086 經常受到記憶體訪問的瓶頸,包括代碼獲取。(與 8086 的 16 位總線不同,8088 幾乎總是使用 8 位總線通過吸管呼吸)。
dec cx是 1 個位元組,jnz rel8是 2 個位元組。
所以總共 3 個位元組,而loop rel8.
8086 的性能可以通過計算記憶體訪問次數并乘以 4 來近似,因為它的 6 位元組指令預取緩沖區允許它與其他指令的解碼和執行重疊代碼獲取。(除了這樣的非常慢的指令mul會在最多三個 2 位元組提取后讓緩沖區填滿。)
另請參閱提高二進制效率 -> 8086 的格雷碼,以獲取針對 8086進行優化的示例,以及指向更多資源(如指令時序表)的鏈接。
https://www2.math.uni-wuppertal.de/~fpf/Uebungen/GdR-SS02/opcode_i.html有 8086 的指令時序(我認為取自英特爾手冊,如 njuffa 的回答中所參考),但這些只是執行,當 fetch 不是瓶頸時。(即只是從預取緩沖區解碼。)
解碼/執行時間,不包括獲取:
DEC Decrement
operand bytes 8088 186 286 386 486 Pentium
r8 2 3 3 2 2 1 1 UV
r16 1 3 3 2 2 1 1 UV
r32 1 3 3 2 2 1 1 UV
mem 2 d(0,2) 23 EA 15 7 6 3 3 UV
Jcc Jump on condition code
operand bytes 8088 186 286 386 486 Pentium
near8 2 4/16 4/13 3/7 m 3/7 m 1/3 1 PV
near16 3 - - - 3/7 m 1/3 1 PV
LOOP Loop control with CX counter
operand bytes 8088 186 286 386 486 Pentium
short 2 5/17 5/15 4/8 m 11 m 6/7 5/6 NP
所以即使忽略代碼獲取差異:
decjnz采用 3 16 = 19 個周期在 8086 / 8088 上解碼/執行。- 在
loop8086 / 8088 上解碼/執行需要 17 個周期。
(采用的分支在 8086 上很慢,并且丟棄了預取緩沖區;沒有分支預測。IDK 如果這些時間包括任何懲罰,因為它們顯然不適用于其他指令和未采用的分支。)
除了代碼預取緩沖區之外,8088/8086 沒有流水線。完成一條指令的執行并開始下一條指令的解碼/執行需要一些時間;即使是最便宜的指令(如mov reg,reg/ shift / rotate / stc/ std/ 等)也需要 2 個周期。奇怪地超過nop(3個周期)。
uj5u.com熱心網友回復:
查看“8086/8088 用戶手冊:程式員和硬體參考”(英特爾 1989 年)確認這LOOP比組合快一點DEC CX; JNZ。DEC占用 3 個時鐘周期,JNZ占用 4 個(未占用)或 16 個(占用)周期。所以組合需要 7 或 19 個周期。LOOP另一方面,需要 5 個周期(未采用)或 17 個周期(采用),以節省 2 個周期。
我在手冊中沒有看到任何描述為什么LOOP更快的內容。由于操作碼位元組數的減少,更快的指令獲取似乎是一個合理的假設。
根據“80286 和 80287 程式員參考手冊”(Intel 1987),LOOP仍然比離散替換有一點優勢,因為它需要 8 個周期,而不需要 4 個周期,而組合在兩者中都需要 1 個周期例(DEC2 個周期;JNZ7 或 3 個周期)。
8086 微碼已被反匯編,因此理論上可以查看這兩種情況的內部操作順序,以準確確定為什么LOOP更快,如果有人愿意的話。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/424412.html
