I observed a weird behavior regarding the memory usage of derived data types. The following fortran90 code demonstrates the issue.
module prec
implicit none
integer, parameter :: d_t = selected_real_kind(15,307)
end module
module typdef
use prec
implicit none
type level_2
real(kind=d_t), allocatable :: lev_3(:)
end type
type level_1
type(level_2),allocatable :: lev_2(:,:)
end type
type array
type(level_1),allocatable :: lev_1(:,:)
end type
end module
program mem_test
use prec
use typdef
implicit none
integer :: n,i,j,k,l,m,egmax,niter,ncells,namom,nsmom
real(kind=d_t),allocatable :: simple_array(:,:,:,:,:)
type(array) :: fancy_array
real(kind=d_t) :: it
egmax=7
niter=2
ncells=3000000
namom=1
nsmom=1
!
!
!
allocate( simple_array(egmax,niter,ncells,namom,nsmom) )
!
!
!
allocate( fancy_array%lev_1(egmax,niter))
do i=1,niter
do j=1,egmax
allocate( fancy_array%lev_1(j,i)%lev_2(ncells,namom) )
end do
end do
do i=1,niter
do j=1,egmax
do k=1,namom
do l=1,ncells
allocate( fancy_array%lev_1(j,i)%lev_2(l,k)%lev_3(nsmom) )
end do
end do
end do
end do
!
do n=1,100000
it=0.0_d_T
do i=1,100000
it=it+1.0_d_t
end do
end do
!
!
deallocate(simple_array)
deallocate(fancy_array%lev_1)
end program
I want to store data in a multi-dimensional array (egmax*niter*ncell*namom*nsmom double precision numbers). I did that in two different ways:
- A multidimensional standard array "simple_array(egmax,niter,...,)"
- A nested derived data structure "fancy_array" as defined in the piece of code that I provided.
I compiled the code using
ifort -g -o test.exe file.f90
I ran it in valgrind and compared the memory consumption of simple_array and fancy_array. simple_array uses about 300Mb as expected while fancy_array uses 3Gb (10 times as much) even though it stores the same number of real numbers. Therefore, it should also consume only 300Mb.
Running a simpler test case, where the derived type is only one level deep, e.g.
type level_1
real(kind=d_t),allocatable :: subarray(:)
end type
type array
type(level_1),allocatable :: lev_1(:)
end type
consumes exactly the amount of memory I am expecting it to. It does not consume 10x as much memory. Has anyone observed similar behavior or has any clue why this would occur? My only idea for the reason of the described behavior is that fancy_array alocated non-contiguous memory and fortran somehow needs to keep track of it, hence the increase in memory consumption. I would appreciate any input or similar observations.
Thanks for your help.
Sebastian