gpt4 book ai didi

performance - 是什么导致了这个微不足道的 Fortran 代码的运行时差异?

转载 作者:行者123 更新时间:2023-12-02 06:06:52 25 4
gpt4 key购买 nike

我在这个微不足道的程序中观察到一个非常奇怪的效果

module Moo 
contains
subroutine main()
integer :: res
real :: start, finish
integer :: i

call cpu_time(start)

do i = 1, 1000000000
call Squared(5, res)
enddo
call cpu_time(finish)

print '("Time = ",f6.3," seconds.")',finish-start
end subroutine

subroutine Squared(v, res)
integer, intent(in) :: v
integer, intent(out) :: res

res = v*v
end subroutine

! subroutine main2()
! integer :: res
! real :: start, finish
! integer :: i
!
! call cpu_time(start)
!
! do i = 1, 1000000000
! res = v*v
! enddo
! call cpu_time(finish)
!
! print '("Time = ",f6.3," seconds.")',finish-start
! end subroutine

end module
program foo
use Moo
call main()
! call main2()
end program

Mac 上的编译器是 gfortran 4.6.2。如果我用 -O0 编译并运行程序,时间是 4.36 秒。如果我取消注释子例程 main2(),而不是它的调用,时间平均变为 4.15 秒。如果我还取消注释 call main2(),第一个时间变为 3.80,第二个时间变为 1.86(可以理解,我没有函数调用)。

我比较了第二种和第三种情况(例程未注释;调用已注释和未注释)中生成的汇编器,它们完全相同,除了 main2 例程的实际调用。

代码如何从对将来要发生的例程的调用中获得这种性能提升,并且结果代码基本上没有差异?

最佳答案

我注意到的第一件事是您的程序太短,无法进行适当的基准测试。您平均使用多少次运行?什么是标准偏差?我在您的代码中添加了一个嵌套的 do 循环以使其更长:

do i = 1, 1000000000
do j=1,10
call Squared(5, res)
enddo
enddo

我只查看了案例 1 和案例 2(main2 已注释和未注释),因为案例 3 不同且与此比较无关。我预计情况 2 的运行时间会略有增加,因为需要将更大的可执行文件加载到内存中,即使该部分未在程序中使用。

所以我为情况 1 和情况 2 对三个编译器进行了计时(每个运行 3 次):

pgf90 10.6-0 64 位目标 x86-64 Linux -tp istanbul-64

Intel(R) Fortran Intel(R) 64 Compiler XE,适用于在 Intel(R) 64 上运行的应用程序,版本 12.0.2.137 Build 20110112

GNU Fortran (GCC) 4.1.2 20080704 (Red Hat 4.1.2-51)

在 AMD Opteron(tm) 处理器 6134 上

我的脚本的输出是:

exp 1 with pgf90:
Time = 30.619 seconds.
Time = 30.620 seconds.
Time = 30.686 seconds.
exp 2 with pgf90:
Time = 30.606 seconds.
Time = 30.693 seconds.
Time = 30.635 seconds.
exp 1 with ifort:
Time = 77.412 seconds.
Time = 77.381 seconds.
Time = 77.395 seconds.
exp 2 with ifort:
Time = 77.834 seconds.
Time = 77.853 seconds.
Time = 77.825 seconds.
exp 1 with gfortran:
Time = 68.713 seconds.
Time = 68.659 seconds.
Time = 68.650 seconds.
exp 2 with gfortran:
Time = 71.923 seconds.
Time = 74.857 seconds.
Time = 72.126 seconds.

注意情况 1 和情况 2 之间的时间差对于 gfortran 最大,对于 pgf90 最小。

编辑:在 Stefano Borini 指出我忽略了一个事实,即使用对 cpu_time 的调用只对循环进行基准测试,可执行加载时间不在考虑范围之内。 AShelley 的回答表明了一个可能的原因。对于更长的运行时间,两种情况之间的差异变得很小。仍然 - 我观察到 gfortran 的显着差异(见上文)

关于performance - 是什么导致了这个微不足道的 Fortran 代码的运行时差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8344910/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com