Hi all. I was reading the discussion on
Why is the Fortran intrinsic function "spread" often slower than explicit iteration
https://stackoverflow.com/questions/55717904/why-is-the-fortran-intrinsic-function-spread-often-slower-than-explicit-iterat
and wanted to try it myself. I modified the code provided by Steve Lionel in the answer (see the end of this message) and got the following timings (compiled using gfortran -O3, but similar results with -O0, version 9.4.0)
Iteration 1 4.42133093
Spread 1 0.309983253
Iteration 3 0.212992191
Spread 3 0.917150021
So it seems that the answer to the question should you use spread or do is it depends on the dimension that you are iterating over. Is there a consistent optimal code for performing these type of calculations?
Whoever told you that do loops were to be avoided at all costs?
Whoever told you that do loops were to be avoided at all costs?
On Tuesday, 14 June 2022 at 16:17:49 UTC+1, Ron Shepard wrote:
Whoever told you that do loops were to be avoided at all costs?
No one told me that. I am looking for a consistent way to program such calculations.
There is an old saying, credited to D. Knuth:
"premature optimization is the root of all evil"
Unless it makes a significant difference in actual time, as in more time
than it takes to discuss, write in the way that is most readable.
Hi all. I was reading the discussion on
Why is the Fortran intrinsic function "spread" often slower than explicit iteration
https://stackoverflow.com/questions/55717904/why-is-the-fortran-intrinsic-function-spread-often-slower-than-explicit-iterat
and wanted to try it myself. I modified the code provided by Steve Lionel in the
answer (see the end of this message) and got the following timings (compiled using
gfortran -O3, but similar results with -O0, version 9.4.0)
Iteration 1 4.42133093
Spread 1 0.309983253
Iteration 3 0.212992191
Spread 3 0.917150021
So it seems that the answer to the question should you use spread or do is it depends on the dimension that you are iterating over. Is there a consistent optimal code for performing these type of calculations?
-------------------------------------------------------------------
module benchmarks
implicit none
integer, parameter :: n=500
integer :: j
real :: d2(n,n)
real :: d3(n,n,n)
contains
! Iteration 1
subroutine benchmark_i1(res,n)
integer n
real, intent(out) :: res(n,n,n)
do j = 1, n
res(j,:,:) = d2*d3(j,:,:)
end do
end subroutine
! Spread 1
subroutine benchmark_s1(res,n)
integer n
real, intent(out) :: res(n,n,n)
res = d3*spread(d2, 1, n)
end subroutine
!Iteration 3
subroutine benchmark_i3(res,n)
integer n
real, intent(out) :: res(n,n,n)
do j = 1, n
res(:,:,j) = d2*d3(:,:,j)
end do
end subroutine
! Spread 3
subroutine benchmark_s3(res,n)
integer n
real, intent(out) :: res(n,n,n)
res = d3*spread(d2, 3, n)
end subroutine
end module
program main
use benchmarks
real :: tstart,tend
real :: res(n,n,n)
call random_number(d2)
call random_number(d3)
! Iteration
call cpu_time(tstart)
call benchmark_i1(res,n)
call cpu_time(tend)
write(*,*) 'Iteration 1', tend-tstart, sum(res)
! Spread
call cpu_time(tstart)
call benchmark_s1(res,n)
call cpu_time(tend)
write(*,*) 'Spread 1', tend-tstart, sum(res)
! Iteration
call cpu_time(tstart)
call benchmark_i3(res,n)
call cpu_time(tend)
write(*,*) 'Iteration 3', tend-tstart, sum(res)
! Spread
call cpu_time(tstart)
call benchmark_s3(res,n)
call cpu_time(tend)
write(*,*) 'Spread 3', tend-tstart, sum(res)
end program
- array syntaxes can be more or less readable than the equivalent do
loops, depending on the cases. But I tend to find spread() less readable
and generally prefer do loops. But it's also a matter of personal preferences.
- apart maybe for some trivial cases, spread() will always be less
efficient than the equivalent do loops, because most of time the compiler
has to allocate and populate a temporary array (and in addition this can result in memory issues if this is a large array)
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 159 |
Nodes: | 16 (0 / 16) |
Uptime: | 99:06:05 |
Calls: | 3,209 |
Files: | 10,563 |
Messages: | 3,009,783 |