Eu escrevi um programa fortran para simular o sistema molecular. Eu o desenvolvi em um computador desktop cujo processador é um Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
. Depois, para iniciar a simulação em larga escala, usei blades de computação cujos processadores são AMD Opteron(tm) Processor 6176 @ 2.3 GHz
. Fiquei surpreso porque o tempo de execução é aumentado por um fator de cerca de 3.
Então, decidi aprender a usar perf
, asm
, ... para otimizar o programa. Depois de muita coisa, finalmente escrevi este pequeno programa e ainda tenho um fator de cerca de 3.
program simple_pgm
integer :: i, res
res = 0
do i=1,1000000000
res = res + i
enddo
write(*,*) res
end program simple_pgm
Comando de compilação:gfortran -g -Wall -O2 simple.f90 -o simple
Quando olhei annotate MAIN__
no perf report -n
, o código assembler é mais ou menos o mesmo.
No processador i7:
│ res = 0 │ do i=1,1000000000 │ mov $0x1,%eax │ xchg %ax,%ax │ res = res + i 1095 │10: add %eax,%edx │ do i=1,1000000000 1 │ add $0x1,%eax │ cmp $0x3b9aca01,%eax │ ↑ jne 10 │ enddo
E no Opteron:
│ res = 0 │ do i=1,1000000000 │ mov $0x1,%eax │ program simple_pgm │ sub $0x220,%rsp │ nop │ res = res + i 1972 │10: add %eax,%edx │ do i=1,1000000000 1524 │ add $0x1,%eax │ cmp $0x3b9aca01,%eax │ ↑ jne 10 │ enddo
Gostaria de saber porque na sample
coluna, para a instrução add $0x1,%eax
, o valor é muito grande para o processador Opteron ( 1524
). E isso poderia explicar o fator de velocidade de execução?
Obrigado pela resposta. Como estou aprendendo ASM, processador e arquitetura de computador, perf, ... (muitas coisas para um iniciante), quaisquer comentários, sugestões serão apreciadas. Estou ciente de que posso estar no caminho errado.
AMD Opteron 6176 usou a microarquitetura K10, versus Intel Core i7 6700 usando a microarquitetura Skylake. O K10 é muito antigo, aparentemente muito antigo para ter suas informações listadas no uops.info ou para estar disponível em analisadores de código.
Seguindo as informações de microarquitetura de Agner Fogs , parece que o K10 precisava de pelo menos 2 ciclos por iteração de pequenos loops. O Skylake não tem essa limitação e, neste caso específico, deve ser capaz de atingir 1 ciclo por iteração.
0,25 ns por iteração (supondo que o i7 6700 funcione a 4 GHz turbo) é quase (mas não totalmente) 3 vezes mais rápido que 0,63 ns por iteração (supondo que o Operon funcione a 3,2 GHz turbo, essa informação não é muito bem suportada e talvez a frequência turbo máxima não tenha sido usada).