來自Agner Fog's "Optimizing Assembly" guide,第12.7節:循環示例。其中一段討論的示例代碼:依賴鏈分析
[...]奔騰M分析:... 13 uops在每時鐘3 =一個迭代每4.33c退休時間。
循環中有一個依賴鏈。等待時間爲:對於 存儲器讀取有2個,對於乘法有5個,對於相減有3個,對於存儲器 寫有3個,總計13個時鐘週期。這是退休時間的三倍,但它不是循環攜帶的依賴關係,因爲每次迭代的結果都保存到內存中,並且在下一次迭代中不會重複使用 。無序執行機制和 流水線使得每個計算可以在前面的計算完成之前 之前開始。唯一的循環進行 依賴鏈是
add eax,16
擁有的只有1
## Example 12.6b. DAXPY algorithm, 32-bit mode
[...] ; not shown: initialize some regs before the loop
L1:
movapd xmm1, [esi+eax] ; X[i], X[i+1]
mulpd xmm1, xmm2 ; X[i] * DA, X[i+1] * DA
movapd xmm0, [edi+eax] ; Y[i], Y[i+1]
subpd xmm0, xmm1 ; Y[i]-X[i]*DA, Y[i+1]-X[i+1]*DA
movapd [edi+eax], xmm0 ; Store result
add eax, 16 ; Add size of two elements to index
cmp eax, ecx ; Compare with n*8
jl L1 ; Loop back
等待時間我不明白爲什麼依賴鏈不增加整體吞吐量。我知道只有找到最壞的瓶頸纔是重要的。在考慮依賴鏈之前確定的最糟糕的瓶頸是融合域uop吞吐量,每次迭代4.33個週期。我不明白爲什麼依賴鏈不是比那更大的瓶頸。
我看到作者解釋說它與無序執行和流水線連接,但我看不到它。不過,我的意思是,只有乘法會導致延遲5個週期,所以只有這個值大於4個週期。
我也無法理解爲什麼筆者不關心的依賴性在這裏:
add eax, 16 -> cmp eax, ecx -> jl L1
畢竟,之前cmp
和cmp
必須jl
之前執行除了必須執行。
PS:後面的段落標識最大的瓶頸爲奔騰M作爲解碼,將其限制到每6C一次迭代,因爲128B矢量OPS進行解碼,以每兩個微指令。請參閱Agner Fog的指南以瞭解其他分析,以及Core2,FMA4推土機和Sandybridge的分析+調整。
比較/分支對將被預測,因此它不會真正計數。除此之外,我不知道你在問什麼 – harold
你能否把Agner的文檔鏈接起來,並陳述你所引用的部分和範例? –