Hi,
I'm seeing strange allocation behavior (actually, deallocation
behavior) with Absoft Pro Fortran 6.0 on Linux. I've just sent
email to their support line, but in the meantime I thought I'd ask
others to try my little test program on compilers that I've
not tried.
I'm particularly interested in other f90 compilers for Linux,
but would like to compile results for as many compilers/platforms
as possible (within reason :-) ).
Here are the results I obtained for Linux-x86 (Absoft Pro F90 6.0),
SGI, TRU64, HPUX, AIX and SunOS. "Recent" (but not necessarily the
latest) compilers are used in each case.
The program included below goes through the following procedure:
ALLOCATE int array of size 10000 ints
DEALLOCATE the same array
ALLOCATE the same array to size 9999 ints
DEALLOCATE the same array
...
ALLOCATE the same array to size 1 int
DEALLOCATE the same array
Thus, the sum of the ALLOCATE sizes is 10000*10001/2 = 50005000 ints.
Since each ALLOCATE beyond the first specifies a smaller size
than the preceding one, the storage should be re-usable, and
the process should not grow significantly after the first allocation.
If no memory is reutilized at all, we expect the memory to grow
by a factor of 50005000/10000, or approx. 5000, over the course of
the process. To rounding error (getting the process size from
"top" or "ps"), it indeed seems to be the case that memory is
not being reused when the code is compiled with Absoft Pro F90
6.0 / Linux-x86.
Below, please find results from Absoft on Linux, as well as from
native compilers on SGI, AIX, TRU64, HP and SunOS. Absoft is
alone in failing to reuse DEALLOCATEd storage. A similar
C program under Linux-x86 (compiled with gcc) exhibits the expected
reuse of memory.
Colleagues report that at least one other Linux F90 does appear
to reuse memory, as expected.
Here are my results, followed by the program. The SZ and RSS
values are typed into the program by hand, then reported at
the end.
---------------------------------------------------
absoft pro fortran 6.0, Linux x86
Starting array size, sum of allocations = 10000 50005000
When SZ RSS
Before first alloc 372 372
After first alloc 384 384
After last alloc 38632 38632
Over-allocation factor 3188.33 3188.33
---------------------------------------------------
sgi
Starting array size, sum of allocations = 10000 50005000
When SZ RSS
Before first alloc 277 119
After first alloc 279 123
After last alloc 279 124
Over-allocation factor 1.00 1.25
---------------------------------------------------
aix
Starting array size, sum of allocations = 10000 50005000
When SZ RSS
Before first alloc 106 172
After first alloc 112 184
After last alloc 144 216
Over-allocation factor 6.33 3.67
---------------------------------------------------
tru64
Starting array size, sum of allocations = 10000 50005000
When SZ RSS
Before first alloc 304 304
After first alloc 320 320
After last alloc 344 344
Over-allocation factor 2.50 2.50
---------------------------------------------------
hp
Starting array size, sum of allocations = 10000 50005000
When SZ RSS
Before first alloc 19 19
After first alloc 23 23
After last alloc 31 31
Over-allocation factor 3.00 3.00
---------------------------------------------------
sunos
Starting array size, sum of allocations = 10000 50005000
When SZ RSS
Before first alloc 10784 1480
After first alloc 10824 1496
After last alloc 10824 1536
Over-allocation factor 1.00 3.50
---------------------------------------------------
! start program
PROGRAM TRY
! Tests out F90 allocation and deallocation
IMPLICIT NONE
INTEGER,PARAMETER :: STARTING_ARRAY_SIZE = 10001
INTEGER,PARAMETER :: MAXITER = 10000
INTEGER :: ITER, ARRAY_SIZE
INTEGER,ALLOCATABLE :: IAR (:)
INTEGER :: SIZES_BEFORE_ALLOC( 2 )
INTEGER :: SIZES_AFTER_FIRST_ALLOC( 2 )
INTEGER :: SIZES_AFTER_LAST_ALLOC( 2 )
INTEGER :: TOTAL_ALLOC = 0
WRITE( 6, '(A)' )'Please use integers for all values entered.'
DO ITER = 1, MAXITER
!!! Prompt user for sizes from 'top' before and after 1st alloc: */
IF( ITER .EQ. 1 )THEN
WRITE( 6, '(A)', ADVANCE='NO' )
& 'Before 1st alloc; enter SZ, RSS from ''top'' or ''ps'': '
READ( 5, * ) SIZES_BEFORE_ALLOC
ELSE IF( ITER .EQ. 2 )THEN
WRITE( 6, '(A)', ADVANCE='NO' )
& 'After 1st alloc; enter SZ, RSS from ''top'' or ''ps'': '
READ( 5, * ) SIZES_AFTER_FIRST_ALLOC
ENDIF
! Deallocate if the array is already allocated:
IF( ITER .GT. 1 ) THEN
DEALLOCATE( IAR )
END IF
! Allocate the array:
ARRAY_SIZE = STARTING_ARRAY_SIZE - ITER
TOTAL_ALLOC = TOTAL_ALLOC + ARRAY_SIZE
ALLOCATE( IAR(ARRAY_SIZE) )
END DO
WRITE( 6, '(A)', ADVANCE='NO' )
& 'After last alloc; enter SZ, RSS from ''top'' or ''ps'': '
READ( 5, * ) SIZES_AFTER_LAST_ALLOC
WRITE( 6, '(A,I10,I20)' )
& 'Starting array size, sum of allocations = ',
& STARTING_ARRAY_SIZE-1, TOTAL_ALLOC
WRITE( 6, '(A30,2A20)' )'When', 'SZ', 'RSS'
WRITE( 6, '(A30,2I20)' )
& 'Before first alloc',
& SIZES_BEFORE_ALLOC
WRITE( 6, '(A30,2I20)' )
& 'After first alloc',
& SIZES_AFTER_FIRST_ALLOC
WRITE( 6, '(A30,2I20)' )
& 'After last alloc',
& SIZES_AFTER_LAST_ALLOC
WRITE( 6, '(A30,2F20.2)' )
& 'Over-allocation factor',
& ( SIZES_AFTER_LAST_ALLOC(1) - SIZES_BEFORE_ALLOC(1) )
& / DBLE( SIZES_AFTER_FIRST_ALLOC(1) - SIZES_BEFORE_ALLOC(1) ),
& ( SIZES_AFTER_LAST_ALLOC(2) - SIZES_BEFORE_ALLOC(2) )
& / DBLE( SIZES_AFTER_FIRST_ALLOC(2) - SIZES_BEFORE_ALLOC(2) )
END
! end program
--
--
** Whether the playing field is level depends on the coordinate system. ***
********* Peter S. Shenkin; Schrodinger, Inc.; (201)433-2014 x111 *********
*********** [log in to unmask]; http://www.schrodinger.com ***********
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|