0

Compiling the following fortran90 program takes minutes

program implloop
 implicit none

 integer, parameter :: dp = selected_real_kind(15)
 integer(dp) :: i
 real(dp), allocatable :: array(:)
 real(dp) :: t1 , t2

 call cpu_time(t1)

 allocate( array(10**8) )
 array = [( sqrt(real(i,dp)) , i = 1 , 10**8 )]

 call cpu_time(t2)
 write(*,*) t2-t1

end program

It is compiled with GNU Fortran (Debian 6.3.0-18+deb9u1) 6.3.0 20170516.

On the other hand, if compiled using a do-loop,

program implloop
 implicit none

 integer, parameter :: dp = selected_real_kind(15)
 integer(dp) :: i
 real(dp), allocatable :: array(:)
 real(dp) :: t1 , t2

 call cpu_time(t1)

 allocate( array(10**8) )

 do  i = 1 , 10**8 
   array(i) = sqrt(real(i,dp))
 end do

 call cpu_time(t2)
 write(*,*) t2-t1

end program

it is ready in a second. What is the reason behind this compile-time difference?

pawel_winzig
  • 902
  • 9
  • 28
  • Please use tag [tag:fortran] for all Fortran questions. – Vladimir F Героям слава Mar 16 '20 at 18:00
  • How much memory does your machine have? https://groups.google.com/forum/#!topic/comp.lang.fortran/8nmVW6nK8eI might be relevant. – Ian Bush Mar 16 '20 at 21:03
  • BTW please learn why real(8) and similar is not recommended and definitely not portable, see for instance https://stackoverflow.com/questions/838310/fortran-90-kind-parameter . Given you are using non default kind integer variables it would also be good practice to use the appropriate kinds for the relevant integer constants as well. – Ian Bush Mar 16 '20 at 21:33
  • The two programs are not equivalent in that gfortran is trying to build the RHS array expression in the former program and then it does a single assignment. The latter program is doing 10^8 assignments of a scalar result. IOW, you're asking gfortran to create an 10^8 element temporary array. – evets Mar 16 '20 at 23:27
  • @IanBush: I've 16GB, Mem seems not to be the problem, the time difference appears also at smaller loops – pawel_winzig Mar 17 '20 at 07:06
  • @evets: I compiled it also with ifort. There, both compile times were the same. – pawel_winzig Mar 17 '20 at 07:50
  • 2
    ifort /= gfortran. I can only tell you what gfortran does. In the code with the implied-do loop, gfortran is computing 10^8 mpfr_sqrt() functions using MPFR at **compile time**, placing those values in a static temporary array, and then copies those values into your allocated memory after checking that re-allocation is not required. In the do-loop code, gfortran is generating a loop that calls __builtin_sqrt() 10^8 times. Each evaluation of __builtin_sqrt() is assigned to an array element. There is no checking for re-allocation, and __builtin_sqrt() is computed at **runtime**. – evets Mar 17 '20 at 14:16

0 Answers0