我在在线资源中发现 IvyBridge 有 3 个 ALU。于是我写了一个小程序来测试:
global _start
_start:
mov rcx, 10000000
.for_loop: ; do {
inc rax
inc rbx
dec rcx
jnz .for_loop ; } while (--rcx)
xor rdi, rdi
mov rax, 60 ; _exit(0)
syscall
我编译并运行它perf
:
$ nasm -felf64 cycle.asm && ld cycle.o && sudo perf stat ./a.out
输出显示:
10,491,664 cycles
乍一看似乎是有道理的,因为在循环中有 3 条独立指令(2inc
和 1 dec
)使用 ALU,所以它们一起计算 1 个周期。
但我不明白的是为什么整个循环只有 1 个循环?jnz
取决于 的结果dec rcx
,它应该算 1 个周期,这样整个循环就是 2 个周期。我希望输出接近20,000,000 cycles
.
我还尝试将第二个inc
从更改inc rbx
为inc rax
,这使得它依赖于第一个inc
。结果确实变得接近20,000,000 cycles
,这表明依赖关系会延迟一条指令,使它们不能同时运行。那么为什么jnz
特别呢?
我在这里缺少什么?