Dear Damian,

Thank you for your interest. I have added two loops to the earlier code, so now 
there are four (nested) loops. The first two loops compare the time of simple 
arithmetic and ieee_next_after as described in the original email. The third 
and fourth loops are the absolute timing tests that you requested.

The third loop in the appended code iterates over the 32-bit integers and at 
each iteration a simple arithmetic operation is performed (that cannot be 
optimized away). The fourth loop iterates over the 32-bit reals from 
-huge(0.0_real32) to huge(0.0_real32) by way of the ieee_next_after function. 
The timings are reported and again we observe the factor of about 200 
difference. Compiling with `gfortran -O5` I get 3.9 seconds for the third loop 
and 883 seconds for the fourth loop on my Intel i7-1165G7.

Compiling with `-O0` makes no significant difference to the times for 
ieee_next_after, but the simple arithmetic tests take longer by about a factor 
of two. Nothing unusual there.

Revised code here:

program main
  !..use and access
  use iso_fortran_env, only : int32, real32, real64
  use ieee_arithmetic
  implicit none
  !..data
  integer, parameter :: m=10000, n=10000
  integer :: i, j
  integer (kind=int32) :: i32, j32
  real (kind=real64) :: tim0, tim1, t0, r
  real (kind=real32) :: t32, r32
  !..executable part
  r = 0
  call cpu_time (tim0)
  do i = 0, m-1
     call random_number (t0)
     do j = 0, n-1
        t0 = t0*(1-epsilon(t0))
        r = r+t0
     end do
  end do
  call cpu_time (tim1)
  write (*,*) 'simple arithmetic:', tim1-tim0, r
  r = 0
  call cpu_time (tim0)
  do i = 0, m-1
     call random_number (t0)
     do j = 0, n-1
        t0 = ieee_next_after(t0,0.0_real64)
        r = r+t0
     end do
  end do
  call cpu_time (tim1)
  write (*,*) 'ieee_next_after:', tim1-tim0, r
  j32 = huge(0_int32)
  i32 = -j32-1
  r32 = 0
  call cpu_time (tim0)
  do while (i32.ne.j32)
     r32 = -r32+i32
     i32 = i32+1
  end do
  call cpu_time (tim1)
  write (*,*) '2^32 simple arithmetic:', tim1-tim0, r32
  t32 = huge(0.0_real32)
  r32 = -t32
  call cpu_time (tim0)
  do while (r32.ne.t32)
     r32 = ieee_next_after(r32,t32)
  end do
  call cpu_time (tim1)
  write (*,*) '2^32 ieee_next_after:', tim1-tim0, r32
  stop
end program main

Bas Braams

----- Original Message -----
From: "Damian McGuckin" <dami...@esi.com.au>
To: "B J Braams" <b.j.bra...@cwi.nl>
Cc: "bug-gcc" <bug-...@gnu.org>
Sent: Sunday, 10 August, 2025 14:27:14
Subject: Re: Very high cost of ieee_next_after function

Can you please write a fortran program which uses real (real*4 or 32-bit 
real) and, starting from negative infinity, uses nextafterf to step 
through every single real up to  positive infinity.  How long does this 
take please?

Thanks - Damian

Reply via email to