如何确定CPE:周期每元(How to determine CPE: Cycles Per Elem

2019-09-17 00:08发布

如何确定一个程序的CPE? 例如,我有一个循环此组件的代码:

# inner4: data_t = float
# udata in %rbx, vdata in %rax, limit in %rcx,
# i in %rdx, sum in %xmm1
1 .L87:                                   # loop:
2   movss  (%rbx,%rdx,4), %xmm0           #  Get udata[i]
3   mulss  (%rax,%rdx,4), %xmm0           #  Multiply by vdata[i]
4   addss  %xmm0, %xmm1                   #  Add to sum
5   addq  $1, %rdx                        #  Increment i
6   cmpq  %rcx, %rdx                      #  Compare i:limit
7   jl .L87                               #  If <, goto loop

我必须找到下界通过使用数据类型float关键路径确定的CPE的。 我认为,关键路径将指向最慢的可能的路径,从而将是一个地方的方案有,因为占用的时钟周期最长数执行mulss指令。

然而,似乎没有被任何明确的方式来确定CPE。 如果一个指令需要两个时钟周期,前者的第一个时钟周期后,另一个需要一个,能后者开始? 任何帮助,将不胜感激。 谢谢

Answer 1:

如果你想知道它是怎么长的需要,你应该衡量它。 执行循环的一些大约10 ^ 10倍,把它需要时间和时钟频率倍增。 你得到的周期由10 ^ 10的总数,除以得到每循环迭代的时钟周期数。

执行时间的理论预测几乎不会是正确的(而且大部分时间为低),因为是决定速度无数影响:

  • 流水线(也可以很容易地在管道约20级)
  • 超标量执行(并行,最多5个指令cmpjl可以稠合)
  • 解码μOps和重新排序
  • 高速缓存或存储器的等待时间
  • 的指令吞吐量(是否有足够的执行端口免费)
  • 指令的延迟
  • 银行的冲突,混淆问题,更深奥的东西

根据不同的CPU并提供了内存访问全部命中L1缓存,相信环路应该需要每次迭代至少3个时钟周期,因为最长的依存关系链是3个元素长。 在较慢的较旧的CPU mulssaddss指令所需要的时间增加。

如果你是在加快的代码,不仅一些理论观察真正感兴趣的,你应该向量化它。 您可以通过4-8的东西的一个因素提高性能类似

.L87:                               # loop:
vmovdqa (%rbx,%rdx,4), %ymm0        #  Get udata[i]..udata[i+7]
vmulps  (%rax,%rdx,4), %ymm0, %ymm0 #  Multiply by vdata[i]..vdata[i+7]
vaddps  %ymm0, %ymm1, %ymm1         #  Add to sum
addq    $8, %rdx                    #  Increment i
cmpq    %rcx, %rdx                  #  Compare i:limit
jl .L87                             #  If <, goto loop

您需要到水平添加所有8个元素之后,当然要确保对齐是32和循环计数器由8整除。



Answer 2:

如果您运行的是英特尔的CPU,你可以找到指令延迟和吞吐量的各种CPU一些好的文档。 这里的链接:

64和IA-32架构优化参考手册



文章来源: How to determine CPE: Cycles Per Element