【发布时间】:2016-08-18 20:11:36
【问题描述】:
我试图理解为什么一些简单的循环会以它们的速度运行
第一种情况:
L1:
add rax, rcx # (1)
add rcx, 1 # (2)
cmp rcx, 4096 # (3)
jl L1
根据IACA,吞吐量是 1 个周期,瓶颈是端口 1,0,5。 我不明白为什么它是 1 个 cylce。毕竟我们有两个循环携带的依赖:
(1) -> (1) ( Latancy is 1)
(2) -> (2), (2) -> (1), (2) -> (3) (Latency is 1 + 1 + 1).
而且这种延迟是循环携带的,所以它应该会减慢我们的迭代速度。
Throughput Analysis Report
--------------------------
Block Throughput: 1.00 Cycles Throughput Bottleneck: Port0, Port1, Port5
Port Binding In Cycles Per Iteration:
-------------------------------------------------------------------------
| Port | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 |
-------------------------------------------------------------------------
| Cycles | 1.0 0.0 | 1.0 | 0.0 0.0 | 0.0 0.0 | 0.0 | 1.0 |
-------------------------------------------------------------------------
| Num Of | Ports pressure in cycles | |
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | |
---------------------------------------------------------------------
| 1 | 1.0 | | | | | | CP | add rax, rcx
| 1 | | 1.0 | | | | | CP | add rcx, 0x1
| 1 | | | | | | 1.0 | CP | cmp rcx, 0x1000
| 0F | | | | | | | | jl 0xfffffffffffffff2
Total Num Of Uops: 3
第二种情况:
L1:
add rax, rcx
add rcx, 1
add rbx, rcx
cmp rcx, 4096
jl L1
Block Throughput: 1.65 Cycles Throughput Bottleneck: InterIteration
Port Binding In Cycles Per Iteration:
-------------------------------------------------------------------------
| Port | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 |
-------------------------------------------------------------------------
| Cycles | 1.4 0.0 | 1.4 | 0.0 0.0 | 0.0 0.0 | 0.0 | 1.3 |
| Num Of | Ports pressure in cycles | |
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | |
---------------------------------------------------------------------
| 1 | 0.6 | 0.3 | | | | | | add rax, rcx
| 1 | 0.3 | 0.6 | | | | | CP | add rcx, 0x1
| 1 | 0.3 | 0.3 | | | | 0.3 | CP | add rbx, rcx
| 1 | | | | | | 1.0 | CP | cmp rcx, 0x1000
| 0F | | | | | | | | jl 0xffffffffffffffef
越是不明白为什么吞吐量是1.65。
【问题讨论】:
-
您是否尝试过运行它并测量每个周期的指令? (将 4096 更改为巨大的东西)。我还没有分析完,但是你的 1+1+1 延迟显然是错误的:
cmp只是稍后的insn读取标志时依赖链的一部分。 -
IACA不是周期精确的。它总是一个近似值,除非在瓶颈很简单的简单情况下。它的 1.65 非常接近观察到的数字。哦,我刚刚注意到 1.65 来自一个不同的循环,带有一个额外的
add。 -
@PeterCordes 我编辑了。
标签: performance assembly optimization x86 micro-optimization