Van Snyder schrieb:
> The actual argument that corresponds to an assumed shape dummy argument
> need not have unit stride along its first dimension.
>
> Do you know what your compilers do in the presence of assumed-shape dummy
> arguments?
Your question should really be addressed to the compiler developers.
As a user, I like to try things out for myself.
Below is a program that does a very simple thing: add the values of an array and
return it.
There are four versions of subroutines to do this:
- a f77 style routine "array_sum0" with dummy argument x(n,*), assuming
contiguous data
- a f77 style routine "array_sum1" with dummy argument x(n,n), assuming data
with
stride 2 in either direction
- a f90 style routine "array_sum2" with dummy argument x(:,:), assuming
contiguous data,
called with contiguous data
- a f90 style routine "array_sum2" with dummy argument x(:,:), assuming
contiguous data,
called with stride 2x2 data
- a f90 style routine "array_sum3" with dummy argument x(:,:), assuming
contiguous data,
called with stride 2x2 data, using inernally the intrinsic SUM()
====================================================================
Here are some results (all compilations with optimization):
Digital Visual Fortran 95 in Intel PC:
f77 loop, contiguous array, sum =32850.339844 time = 3.180000
f77 loop, stride 2x2 array, sum =32850.339844 time = 5.170000
f90 loop, contiguous array, sum =32850.339844 time = 6.530001
f90 loop, stride 2x2 array, sum =32850.339844 time = 8.460001
f90 SUM(stride 2x2 array), sum =32850.343750 time = 8.240000
IBM RS/6000 AIX, with IBM f95 compiler:
f77 loop, contiguous array, sum =32749.095703 time = 2.800000
f77 loop, stride 2x2 array, sum =32749.095703 time = 2.860000
f90 loop, contiguous array, sum =32749.095703 time = 2.819999
f90 loop, stride 2x2 array, sum =32749.095703 time = 2.870000
f90 SUM(stride 2x2 array), sum =32749.095703 time = 2.830000
IBM RS/6000 AIX, with NAG f95 compiler:
f77 loop, contiguous array, sum =32762.779297 time = 2.810000
f77 loop, stride 2x2 array, sum =32762.779297 time = 2.840000
f90 loop, contiguous array, sum =32762.779297 time = 2.740000
f90 loop, stride 2x2 array, sum =32762.779297 time = 2.720000
f90 SUM(stride 2x2 array), sum =32762.779297 time = 2.750000
Hope this may help you.
Sincerely,
Friedrich
====================================================================
And finally the program, if you want to make further tests (let me know about
any further results):
module work
implicit none
contains
subroutine array_sum2(x, s)
real :: x(:,:), s
integer :: i, j
s = 0.0
do j=1,size(x,2)
do i=1,size(x,1)
s = s + x(i,j)
end do
end do
end subroutine array_sum2
subroutine array_sum3(x, s)
real :: x(:,:), s
s = SUM(x)
end subroutine array_sum3
end module work
program AssumedShapeArray
use work
integer, parameter :: m=256, n=512, u=1, itmax=1000
real :: x(m,m)
real :: y(n,n)
real :: s, t0, t
integer :: iter
print *, "program started ..."
call random_number(y)
x(:,:) = y(2:n:2,2:n:2)
call CPU_time(t0)
do iter=1,itmax
call array_sum0(x,m,s)
end do
call CPU_time(t)
write(u,100) "f77 loop, contiguous array, sum =", s, " time =", t-t0
call CPU_time(t0)
do iter=1,itmax
call array_sum1(y,n,s)
end do
call CPU_time(t)
write(u,100) "f77 loop, stride 2x2 array, sum =", s, " time =", t-t0
call CPU_time(t0)
do iter=1,itmax
call array_sum2(x,s)
end do
call CPU_time(t)
write(u,100) "f90 loop, contiguous array, sum =", s, " time =", t-t0
call CPU_time(t0)
do iter=1,itmax
call array_sum2(y(2:n:2,2:n:2),s)
end do
call CPU_time(t)
write(u,100) "f90 loop, stride 2x2 array, sum =", s, " time =", t-t0
call CPU_time(t0)
do iter=1,itmax
call array_sum3(y(2:n:2,2:n:2),s)
end do
call CPU_time(t)
write(u,100) "f90 SUM(stride 2x2 array), sum =", s, " time =", t-t0
print *, " ... program ended."
100 format(2(a,f12.6))
end program
subroutine array_sum0(x,n,s)
implicit none
integer :: n
real :: x(n,*), s
integer :: i, j
s = 0.0
do j=1,n
do i=1,n
s = s + x(i,j)
end do
end do
end subroutine array_sum0
subroutine array_sum1(x,n,s)
implicit none
integer :: n
real :: x(n,n), s
integer :: i, j
s = 0.0
do j=2,n,2
do i=2,n,2
s = s + x(i,j)
end do
end do
end subroutine array_sum1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|