На интернет-ресурсе я обнаружил, что у 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 независимых инструкции (2 inc
и 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
особенный?
Что мне здесь не хватает?
xor edi, edi
будет лучше, чемxor rdi, rdi
, поскольку он короче - person phuclv   schedule 07.01.2019