我写了一个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 运行,该信息没有得到很好的支持,并且也许没有使用最大涡轮频率)。