Performance 如何确定CPE:每个元素的周期

Performance 如何确定CPE:每个元素的周期,performance,architecture,assembly,x86,sse,Performance,Architecture,Assembly,X86,Sse,如何确定程序的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

如何确定程序的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
#inner4:data\u t=float
#%rbx中的udata,%rax中的vdata,%rcx中的限制,
#i以%rdx表示,总和以%xmm1表示
1.L87:#循环:
2个movss(%rbx,%rdx,4),%xmm0#获取udata[i]
3乘(%rax,%rdx,4),%xmm0乘以vdata[i]
4添加%xmm0,%xmm1#添加到总和
5增加1美元,增加1%rdx
6 cmpq%rcx%rdx#比较i:极限

7 jl.L87#如果您运行的是Intel CPU,您可以找到一些关于各种CPU的指令延迟和吞吐量的好文档。以下是链接:


如果你想知道它需要多长时间,你应该测量它。执行循环大约10^10次,取所需时间乘以时钟频率。得到循环总数,除以10^10得到每个循环迭代的时钟周期数

执行时间的理论预测几乎永远不会正确(大部分时间都很低),因为决定速度的因素很多:

  • 管道(管道中可能有20个阶段)
  • 超标量执行(最多可并行执行5条指令,
    cmp
    jl
  • 解码到µOps并重新排序
  • 缓存或内存的延迟
  • 指令的吞吐量(是否有足够的空闲执行端口)
  • 指令的延迟
  • 银行冲突、别名问题和更深奥的东西
根据CPU的不同,如果内存访问全部命中一级缓存,我认为循环每次迭代至少需要3个时钟周期,因为最长的依赖链是3个元素长。在使用较慢的
mulss
addss
指令的较旧CPU上,所需时间会增加

如果你真的对加速代码感兴趣,而不仅仅是一些理论上的观察,你应该把它矢量化。您可以通过以下方式将性能提高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
.L87:#循环:
vmovdqa(%rbx,%rdx,4),%ymm0#获取udata[i]…udata[i+7]
vmulps(%rax,%rdx,4),%ymm0,%ymm0乘以vdata[i]…vdata[i+7]
vaddps%ymm0,%ymm1,%ymm1#相加
增加8美元,增加1%rdx
cmpq%rcx,%rdx#比较i:极限

jl.L87#如果这是一个很难回答的问题,因为所需的周期非常依赖于目标cpu。对于一条指令,不同的CPU可能需要不同数量的周期。一些CPU可能能够在并行管道中无序地运行某些指令(如line5+6,而4正在等待3的结果),而其他CPU则不能。