首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >依赖链分析

依赖链分析
EN

Stack Overflow用户
提问于 2016-04-20 09:16:00
回答 1查看 1.5K关注 0票数 2

来自阿格纳雾的“优化装配”指南的12.7节:一个循环示例。讨论示例代码的段落之一是:

..。对奔腾M的分析:.每时钟3次,13次,每4.33c退休时间重复一次。 循环中有一个依赖链。延迟为:内存读取2次,乘法5次,减法3次,内存写入3次,共13个时钟周期。这是停用时间的三倍,但它不是循环携带的依赖,因为每个迭代的结果被保存到内存中,而不是在下一个迭代中重用。无序执行机制和流水线使得每个计算都可以在前面的计算完成之前开始。唯一的循环携带依赖链是add eax,16,它的延迟仅为1。

代码语言:javascript
复制
## 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次。我不明白为什么依赖链不是比这更大的瓶颈。

  1. 我看到作者解释说,它与无序执行和流水线有关,但我看不见它。不过,我的意思是,只有乘法会导致延迟5个周期,所以只有这个值大于4个周期。
  2. 我也不明白为什么作者不关心这里的依赖关系:毕竟,add eax, 16 -> cmp eax, ecx -> jl L1必须在执行cmp之前执行加法,而cmp必须在jl之前执行。

PS:后面的段落将奔腾M的最大瓶颈确定为解码,将其限制为每6c迭代一次,因为128 B向量ops每解码两个uop。有关分析的其余部分,请参阅Agner的指南,以及Core2、FMA4推土机和沙桥的分析+调优。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-21 03:15:31

  1. mul不是循环携带的依赖链的一部分,因此可以同时从多个迭代中获得mulpd insns。在这里,单个指令的延迟根本不是问题,而是依赖链。每一次迭代都有一个单独的13c依赖链,包括load、mulpd、subpd、store。无序执行是允许多个迭代的uop同时运行的原因。
  2. 每个迭代中的cmp / jl依赖于来自该迭代的add,但下一个迭代中的add不依赖于cmp。推测执行和分支预测意味着控制依赖项(条件分支和间接跳转/调用)不是数据依赖链的一部分。这就是为什么来自一个迭代的指令可以在前一个迭代的jl退出之前开始运行。 相比之下,cmov是一个数据依赖项,而不是一个控件依赖项,因此,无分支循环往往具有循环携带的依赖链。如果分支预测得好的话,这往往比分支的速度慢。 每个循环迭代都有一个独立的cmp/jl依赖链,就像FP依赖链一样。

我不明白为什么依赖链没有增加整个吞吐量。

我不知道这句话是什么意思。我想我能弄清楚你的其他混淆词和措辞。(例如,“链依赖”而不是“依赖链”)。看看我对你问题的编辑,其中一些可能也有助于你的理解。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36739118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档