returns time from a real-time clock, protected against rolling early/easily
same implementation for all machines. might still roll, if not called multiple times per count_max/count_rate
FUNCTION m_walltime() RESULT(wt)
!! returns time from a real-time clock, protected against rolling
!! early/easily
!! @note
!! same implementation for all machines.
!! might still roll, if not called multiple times per count_max/count_rate
#if defined(__LIBXSMM)
USE libxsmm, ONLY: libxsmm_timer_tick, libxsmm_timer_duration
#endif
REAL(KIND=dp) :: wt
#if defined(__LIBXSMM)
wt = libxsmm_timer_duration(0_int_8, libxsmm_timer_tick())
#else
INTEGER(KIND=int_8) :: count
INTEGER(KIND=int_8), SAVE :: count_max, count_rate, cycles = -1, &
last_count
!$ IF (.FALSE.) THEN
! count lies in [0,count_max] and increases monotonically
IF (cycles == -1) THEN ! get parameters of system_clock and initialise
CALL SYSTEM_CLOCK(count_rate=count_rate, count_max=count_max)
cycles = 0
last_count = 0
END IF
CALL SYSTEM_CLOCK(count=count)
! protect against non-standard cases where time might be non-monotonous,
! but it is unlikely that the clock cycled (e.g. underlying system clock adjustments)
! i.e. if count is smaller than last_count by only a small fraction of count_max,
! we use last_count instead
! if count is smaller, we assume that the clock cycled.
IF (count < last_count) THEN
IF (last_count - count < count_max/100) THEN
count = last_count
ELSE
cycles = cycles + 1
END IF
END IF
! keep track of our history
last_count = count
wt = (REAL(count, KIND=dp) + REAL(cycles, KIND=dp)*(1.0_dp + REAL(count_max, KIND=dp))) &
/REAL(count_rate, KIND=dp)
!$ ELSE
!$ wt = OMP_GET_WTIME()
!$ END IF
#endif
END FUNCTION m_walltime