如何确定程序的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。如果一条指令占用两个时钟周期,而另一条指令占用一个时钟周期,那么后者可以在前者的第一个时钟周期之后开始吗?任何帮助都将不胜感激。谢谢
发布于 2012-05-03 07:36:29
如果你想知道它需要多长时间,你应该测量它。执行循环大约10^10次,占用所需的时间,并乘以时钟频率。您可以得到周期的总数,除以10^10就可以得到每次循环迭代的时钟周期数。
执行时间的理论预测几乎永远不会正确(并且大多数时间都是低的),因为有许多影响决定了速度:
cmp和jl可以融合)>H111>指令的吞吐量(是否有足够的空闲执行端口)
根据中央处理器的不同,如果内存访问都命中L1缓存,我认为循环每次迭代至少需要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你需要在这之后水平添加所有8个元素,当然还要确保对齐是32,循环计数器可以被8整除。
发布于 2012-05-03 06:44:28
如果您运行的是Intel CPU,您可以找到一些关于各种CPU的指令延迟和吞吐量的文档。链接如下:
Intel® 64 and IA-32 Architectures Optimization Reference Manual
https://stackoverflow.com/questions/10419316
复制相似问题