Explicit-shape/assumed-size vs. allocatable arrays.
Bart Oldeman
bartoldeman@users.sourceforge.net
Tue Jun 12 15:15:00 GMT 2007
Last summer, when introducing allocatable arrays into some research code
that used to be all F77, I observed that GFortran generated considerably
slower code using allocatable arrays than when passing them to a
subroutine that uses explicit shape or assumed size arrays. The
descriptor stride gets in the way a little.
I checked again in January for a bug report but the issue was fixed
(cool!) However, it seems there are still some smaller things that may be
worth noting.
Below is a simple testcase, that adds two arrays 20000 times. I'm using
explicit loops rather than "c=a+b"; they still seem to be optimized
better.
Results for an Core2 @1.60GHz, in 32-bit mode; execution time in seconds.
Switches used: -msse2 -mfpmath=sse -O -ftree-vectorize -ftree-vectorizer-verbose=1
GFortran version:
4.1: gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Allocatable: 1.492093 (not vectorized)
Explicit-shape: 0.3160200 (not vectorized)
4.2: gcc version 4.2.1 20070528 (prerelease) (Debian 4.2-20070528-1)
Allocatable: 0.2880180 (vectorized)
Explicit-shape: 0.2880180 (vectorized)
4.3: gcc version 4.3.0 20070611 (experimental)
Allocatable: 0.4480280 (vectorized)
Explicit-shape: 0.4320270 (vectorized)
Using -O2 instead of -O:
4.1:
Allocatable: 0.5440340 (not vectorized)
Explicit-shape: 0.2880180 (vectorized)
4.2:
Allocatable: 0.3200190 (not vectorized)
Explicit-shape: 0.3520220 (vectorized)
4.3
Allocatable: 0.3160190 (not vectorized)
Explicit-shape: 0.4400280 (vectorized)
Some conclusions:
* -O2 makes it harder to vectorize the allocatable array operations.
* GFortran 4.2 -O performs very well, better than -O2.
* GFortran 4.3 seems to have some performance regressions.
Can anyone confirm this? Are these know issues or should some be reported
as bugs or enhancement requests in bugzilla?
program test
implicit none
double precision, allocatable, dimension(:) :: a,b,c
integer :: i, j, n
real :: start, finish
n=10000
allocate(a(10000),b(10000),c(10000))
call cpu_time(start)
do i = 1,20000
do j = 1,n
a(j) = b(j)+c(j)
enddo
enddo
call cpu_time(finish)
print *,'Allocatable: ', finish-start
call cpu_time(start)
call add(a,b,c,n)
call cpu_time(finish)
print *,'Explicit-shape: ', finish-start
end program test
subroutine add(a,b,c,n)
implicit none
double precision, dimension(n), intent(in) :: b,c
double precision, dimension(n), intent(out) :: a
integer :: i, j, n
do i = 1,20000
do j = 1,n
a(j) = b(j)+c(j)
enddo
enddo
end subroutine add
More information about the Fortran
mailing list