! Test performance of unformatted sequential with different sized records.
! Janne Blomqvist 2013
program us_perf
  implicit none
  integer, parameter :: d = 8
  integer, parameter :: i64 = selected_int_kind(18)
  integer :: ii
  real(d) :: wspeed, rspeed

  print *, 'Unformatted sequential write/read performance test'
  print *, 'Record size           Write MB/s                 Read MB/s'
  print *, '=========================================================='
  ii = 1
  do
     call run_us_test (ii, wspeed, rspeed)
     print *, ii*4, wspeed, rspeed
     if (ii > 100000) then
        exit
     end if
     ii = ii * 2
  end do

contains
  subroutine run_us_test (n, ws, rs)
    integer, intent(in) :: n
    real(d), intent(out) :: ws, rs
    integer, allocatable :: data(:)
    real(d) :: t1, t2
    integer :: ii, loops
    integer, parameter :: nsize = 10000000 ! 10 MB

    ! Write nsize * log(n + 1) bytes,  each record is n elements of 4 bytes each
    ! + two 4 byte record markers
    loops = nsize * log(n + 1._d) / (n*4._d + 8._d)

    allocate(data(n))
    data = 123
    open(10, file="usperf.dat", form='unformatted', access='sequential', status='replace')
    call wtime(t1)
    do ii = 1, loops
       write (10) data
    end do
    call wtime(t2)
    close(10)
    ws = nsize * log(n+1._d) / 1024**2 / (t2-t1)
    open(10, file="usperf.dat", form='unformatted', access='sequential', status='old')
    call wtime(t1)
    do ii = 1, loops
       read (10) data
    end do
    call wtime(t2)
    close(10, status='delete')
    deallocate(data)
    rs = nsize * log(n+1._d) / 1024**2 / (t2-t1)
  end subroutine run_us_test

  subroutine wtime(t)
    real(d) :: t
    integer(i64):: count, rate
    call system_clock(count, rate)
    t = real(count, d) / rate
  end subroutine wtime
    
end program us_perf
