我写了一个fortran程序来模拟分子系统。我在一台处理器为
Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
的台式计算机上开发了它。之后,为了启动大规模模拟,我使用了处理器为AMD Opteron(tm) Processor 6176 @ 2.3 GHz
的计算刀片。我很惊讶,因为执行时间增加了大约 3 倍。
所以,我决定学习如何使用
perf
,asm
,...来优化程序。
做了很多事情,我终于写了这个短程序,我还有大约3的因子。
program simple_pgm
integer :: i, res
res = 0
do i=1,1000000000
res = res + i
enddo
write(*,*) res
end program simple_pgm
编译命令:
gfortran -g -Wall -O2 simple.f90 -o simple
当我查看
annotate MAIN__
中的perf report -n
时,汇编代码或多或少是相同的。
在 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
在 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
我想知道为什么在
sample
列中,对于指令add $0x1,%eax
,对于Opteron处理器来说,值非常大(1524
)。它可以解释大约执行速度的因素吗?
感谢您的回答。由于我正在学习 ASM、处理器和计算机体系结构、性能……(对于初学者来说有很多东西),任何意见、建议将不胜感激。我知道我 可能走错路了。
AMD Opteron 6176 使用 K10 微架构,而 Intel Core i7 6700 使用 Skylake 微架构。 K10 非常旧,显然太旧了,无法在 uops.info 上列出其信息,也无法在代码分析器中使用。
根据 Agner Fogs 微架构信息,K10 似乎每次小循环迭代至少需要 2 个周期。 Skylake 没有这个限制,在这种特殊情况下,每次迭代应该能够达到 1 个周期。
每次迭代 0.25ns(假设 i7 6700 以 4GHz Turbo 运行)几乎(但不完全)是每次迭代 0.63ns 的 3 倍(假设 Operon 以 3.2GHz Turbo 运行,该信息并没有得到很好的支持,也许没有使用最大涡轮频率)。