Silverfrost Forums

Welcome to our forums

Timing program run time

21 Jul 2013 4:48 #12676

Hello

If I want to hard code into a program a routine to output how long the program to complete the whole task, is there a simple routine for that?

I checked the help and I assume it must work around the use of CPU_TIME to determine how long the program is active?

Basically how does one map:

Program-start to program-end as a timer?

REAL(3) START,FINISH START= CPU_CLOCK@()

! some calculation. . .INSERT MAIN PROGRAM CODE HERE

FINISH= CPU_CLOCK@() PRINT *,FINISH-START,'clocks taken'

or

REAL TIME1, TIME2 CALL CPU_TIME(TIME1) ! Processing... CALL CPU_TIME(TIME2) PRINT *, 'Processing time was ', TIME2-TIME1, ' seconds'

I think the CPU_CLOCK looks right, is that the way to time a program run?

A proper example program would help, not too sure where the thing goes!

Cheers Lester

22 Jul 2013 1:21 #12677

CPU_TIME intrinsic does give a useful measure of processor usage. You might also want to consider system_clock, as this would provide an elapsed time counter. If you are having problems with network disk access, elapsed time is a very useful measure of performance.

      real*8    start_sec, end_sec, x
      integer*4 i
      real*8    get_system_seconds
      external  get_system_seconds
!
      start_sec = get_system_seconds ()
      x = 0.5
      do i = 1,1000000
         x = exp (log (x))
      end do
      write (*,*) x
      end_sec = get_system_seconds ()
      write (*,*) 'Elapsed time =', end_sec-start_sec,' seconds'
      end

      real*8 function get_system_seconds ()     !    Fortran Intrinsic system_clock
!
      integer*8 :: system_clock_now
      integer*8 :: system_clock_start = -1
      integer*8 :: system_clock_rate  = -1
      integer*8 :: get_System_Clock_tick, get_System_Clock_rate
      external     get_System_Clock_tick, get_System_Clock_rate
!
!
      system_clock_now = get_System_Clock_tick ()
!
      if (system_clock_start < 0) then
        system_clock_start = System_Clock_now
        system_clock_rate  = get_System_Clock_rate ()
        write (*,*) '  System_Clock  start  =',system_clock_start
        write (*,*) '  System_Clock  rate   =',system_clock_rate
!
        system_clock_now   = get_System_Clock_tick ()
      end if
!
      get_system_seconds = dble (system_clock_now-system_clock_start) / dble (system_clock_rate)
!
      end function get_system_seconds

       integer*8 function get_System_Clock_tick ()     !     Fortran Intrinsic Routine
!
       integer*4 :: tick
       integer*8 :: first_tick = -1
!
       call system_clock (count=tick)
       if (first_tick < 0) first_tick = tick
       get_System_Clock_tick = tick - first_tick
!
       END function get_System_Clock_tick
 
       integer*8 function get_System_Clock_rate ()     !     Fortran Intrinsic Routine
!
       integer*4 :: rate
!
       call system_clock (count_rate=rate)
       get_System_Clock_rate = rate
!
       END function get_System_Clock_rate
22 Jul 2013 6:03 #12678

I would do something like this

module timer_mod

   implicit none
   private

   public :: start_timer, get_elapsed_seconds

   real(kind(1.0d0)) :: t = 0.0d0

contains

   subroutine start_timer()
      call cpu_time(t)
   end subroutine start_timer

   function get_elapsed_seconds()
      real(kind(1.0d0)) :: get_elapsed_seconds, t1
      call cpu_time(t1)
      get_elapsed_seconds = t1 - t
   end function

end module timer_mod


!** Your program
program main

   use timer_mod, only: start_timer, get_elapsed_seconds

   real(kind(1.0d0)) :: time_taken
   integer :: hours, minutes, seconds

   call start_timer

   ! Your program code here
   !
   !
   !

   time_taken = get_elapsed_seconds()

   seconds = int(time_taken)
   minutes = seconds/60
   hours = minutes/60
   minutes = mod(minutes,60)
   seconds = mod(seconds,60)
   write(*,'('Elapsed CPU time: ',i0,' hours ',i0,' minutes ',i0,' seconds')') hours, minutes, seconds
end program main
22 Jul 2013 11:52 #12679

Lester, David has provided an example of measuring CPU or processor time, while I provided an example of elapsed or clock time. Depending on the type of computation you are doing, you need to consider which one is more relevant to use. You gave an example of comparing your home and work computer performance, although you have not identified the reason for the difference. It is more likely that there would be a difference in the elapsed time between the two computers, while the CPU time might be very similar. Task Manager is a useful tool for measuring program performance, as it can show processor and disk usage (both file access and virtual memory usage). This can help with understanding the program performance. The examples that David and I have provided can be useful for timing the stages of computation, should the reason for the differences in run time be difficult to track. /TIMING can also be a very useful compiler option to use to identify the source of delays. You need to learn how best to use this option. The following is a .bat example of my use of /timing.

del *.obj
del *.mod
del channel_tim.exe
del channel_tim.map

now                                 > ftn95.tce
SET TIMINGOPTS=/TMO /DLM ,

ftn95 channel_tim          /timing >> ftn95.tce
ftn95 get_swell_dir_factor /debug  >> ftn95.tce
ftn95 file                 /debug  >> ftn95.tce
ftn95 time                 /opt    >> ftn95.tce
ftn95 util                 /debug  >> ftn95.tce
slink  main_tim.txt                >> ftn95.tce

dir *.exe
del *.obj

notepad ftn95.tce

now          > channel_profile.tce
channel_tim >> channel_profile.tce

! main_tim.txt
lo channel_tim.obj
lo get_swell_dir_factor.obj
lo file.obj
lo time.obj
lo util.obj
le \\clearwin\\saplib.mem\\saplib.lib
map  channel_tim.map
file channel_tim.exe

In this example channel_tim.f95 is a file that consists of INCLUDE statements of code that I want to time, while the other utility files are not compiled with /timing. This produces two output files, one that can be imported into excel for further analysis. This can be a very useful option for identifying where to put the effort into improving run time performance. /timing works at the subroutine level. There is also a more detailed /profile option that identifies each line of code, but I am yet to use that option.

John

23 Jul 2013 8:39 #12681

Thanks David, John,

This is all useful information. The elapsed time is a good comparison for different systems. As you say, it is also good to find where the programs are slowing down or using more CPU resources; particularly with the programs I have to deal with which are numerically intensive.

Just getting back into coding again after a long gap! So bear with me lol

I am a geologist/geophysicist primarily working on gravity and magnetics data.

Cheers Lester

Please login to reply.