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