Time Functions

Modern Fortran features some basic time functions. On POSIX-compliant systems, the ISO C binding interface allows us to use additional timing routines defined by libc.

Sleep

The sleep routine pauses the program for a given number of seconds:

! time.f90
program main
    ! Sleep for 5 seconds ...
    call sleep(5)
end program main

In order to sleep for less than a second, one can write an interface to the libc routine usleep(), which pauses for a given interval measured in microseconds:

! posix_sleep.f90
program main
    implicit none
    integer :: i
    integer :: t = 500000 ! 500 milliseconds

    interface
        subroutine usleep(useconds) bind(c)
            use, intrinsic :: iso_c_binding, only: c_int32_t
            implicit none
            integer(c_int32_t), value :: useconds
        end subroutine
    end interface

    do i = 1, 10
        print '(a)', 'zzz ...'
        call microsleep(t)
    end do

    contains
        subroutine microsleep(useconds)
            !! Wrapper for `usleep()` that converts integer to c_int32_t.
            use, intrinsic :: iso_c_binding, only: c_int32_t
            implicit none
            integer :: useconds
            call usleep(int(useconds, kind=c_int32_t))
        end subroutine microsleep
end program main

You may want to write a wrapper routine like microsleep() that does the type convertion from integer to c_int32_t.

CPU Time

The intrinsic Fortran routine cpu_time() returns the ellapsed CPU time in microseconds.

Mandelbrot set in Fortran
Fig. 1: The example Mandelbrot program

An example shows the measurement of the time required to compute the Mandelbrot set (fig. 1):

! mandelbrot.f90
program main
    implicit none
    integer, parameter :: width     = 80
    integer, parameter :: height    = 40
    integer, parameter :: max_iter  = 90
    real,    parameter :: threshold = 2.0
    integer            :: x, y
    real               :: re, im
    real               :: t1, t2

    call cpu_time(t1)

    do y = 0, height
        im = -1.5 + real(y) * 3.0 / real(height)

        do x = 0, width
            re = -2.0 + real(x) * 3.0 / real(width)

            if (mandelbrot(cmplx(re, im), max_iter, threshold) < 10) then
                write (*, '(a)', advance='no') ' '
            else
                write (*, '(a)', advance='no') '*'
            end if
        end do

        write (*, '(a)')
    end do

    call cpu_time(t2)
    print '("Time: ", f8.6, " seconds")', t2 - t1

    contains
        function mandelbrot(c, max_iter, threshold)
            !! Calculates Mandelbrot set.
            complex, intent(in) :: c
            integer, intent(in) :: max_iter
            real,    intent(in) :: threshold
            integer             :: mandelbrot
            complex             :: z

            z = (0.0, 0.0)

            do mandelbrot = 0, max_iter
                z = z**2 + c

                if (abs(z) > threshold) &
                    exit
            end do
        end function mandelbrot
end program main