在Fortran中获得确切的运行时间

时间:2019-01-19 04:44:18

标签: fortran benchmarking

我需要设置一个现有的Fortran代码,使其有时间限制(即24小时周期)运行。我正在尝试实现一个简单的运行时计时,该计时可测量代码正在运行的“实际时间”(而不是CPU时间),并执行适当的保存和终止例程。 由于这种检查经常发生,因此我不想真正获得整个白天的时间并从中计算出总的小时/分钟。我更喜欢CPU_TIME()上的内容,并做一个简单的(Current-Start)/3600(我真的只需要几个小时的时间)。

我实际上尝试过以最简单的方式实现CPU_TIME(),它似乎可以工作很短的时间,但是显然随着时间的增加,出现了“漂移”现象,并且我最终运行的时间比实际时间略多限制,它终止了我的代码而没有保存“检查点”。 除了尝试设置小时数下限以解决“漂移”之外,还有没有更精确,更简单的实现方案来在几分钟内获得正确的运行时间?

编辑: 我也尝试过使用system_clock,但是该例程的实际时间和输出时间完全关闭了……我在做什么错了?

INTEGER :: scount,  & ! Starting "time"
           ecount,  & ! Ending "time"
           rate       ! number of clock ticks per second

call system_clock(scount,rate)
...
<CODE>
...
call system_clock(ecount)
timer_elapsed_time = real(ecount-scount,8)/real(rate,8)
write(*,*) "Calculated run time is ",timer_elapsed_time *3600," hours"

解决方案:在某些情况下(例如我的情况),时钟频率可以为real,而不能为integer

2 个答案:

答案 0 :(得分:2)

发布的代码使用整数来获取系统的时钟频率。也可以使用实数变量调用system_clock以返回费率。我的怀疑(现在通过交流交换意见得到了证实)是整数是时钟速率的不正确表示,从而解释了使用system_clock时观察到的不准确性。

OP报告通过使用实数变量作为时钟速率来解决此问题。

答案 1 :(得分:1)

我取决于您希望经过的时间测量的精确度。以下模块将允许您计算时间,精确到毫秒。

module time_keeper

  implicit none
  integer    :: start(8), now(8)

contains

  subroutine startclock( )
    implicit none
    call date_and_time(values=start)
  end subroutine startclock


  subroutine elapsedtime_s( et_s )
    implicit none
    integer             :: diffs(8)=0
    real   , intent(out):: et_s       ! in seconds

    call date_and_time(values=now)

    ! - Find the difference in times
    diffs = now - start

    ! - This works only when the time is measured in a specific month
    if (diffs(3) > 0) then
       diffs(5) = 24*diffs(3) + diffs(5)
    endif

    et_s = diffs(5) * 3600 + diffs(6) * 60 + diffs(7) + 1e-3 * diffs(8)

  end subroutine elapsedtime_s

end module time_keeper

program main

  use time_keeper

  implicit none

  integer     :: x=0, i
  real        :: et_s

  call startclock()
  do i = 1, 1e5
     x = x + 1
  end do

  call elapsedtime_s( et_s )
  write(*,*) et_s

end program main

请注意,time_keeper::elapsedtime_s仅在一个月以内测量时间时有效。如果您还希望将测量结果考虑在内,则可以扩展子例程。那应该很简单。

其他选项包括time keeping librarysystem_clock(请参阅here)。 date_and_time的引用是here