Достижение точного времени выполнения в Фортране - PullRequest
0 голосов
/ 19 января 2019

Мне необходимо настроить существующий код на Фортране для запуска с ограничением по времени (т.е. 24-часовые циклы).Я пытаюсь реализовать простую синхронизацию во время выполнения, которая измеряет «реальное» время (а не время процессора), в котором выполнялся код, и выполняет надлежащую процедуру сохранения и завершения.Так как эта проверка происходит очень часто, я не хочу фактически получать весь дневной период и рассчитывать общее количество часов / минут из этого.Я бы предпочел что-то в строках 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 голосов
/ 20 января 2019

В опубликованном коде используется целое число для получения тактовой частоты системы.system_clock также может быть вызвано с использованием реальной переменной для возврата курса.Мое подозрение, подтвержденное теперь обменом комментариями, заключалось в том, что целое число было неточным представлением тактовой частоты, тем самым учитывая неточность, наблюдаемую при использовании system_clock.

OP-отчетов, устраняющих проблему с помощьюреальная переменная для тактовой частоты.

0 голосов
/ 19 января 2019

Я зависит от того, насколько точно вы хотите, чтобы измеренное время истекло.Следующий модуль позволит вам рассчитать время с точностью до миллисекунд.

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 работает только в том случае, если время измеряется в течение месяца.Если вы хотите, чтобы измерения также учитывались в месяцах, вы можете расширить подпрограмму.Это должно быть просто.

Другие опции включают библиотеку времени хранения , system_clock (см. здесь ).Ссылка для date_and_time здесь

...