我观察到关于派生数据类型的内存使用的奇怪行为。以下 fortran90 代码演示了该问题。
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
我想将数据存储在一个多维数组中(例如max*niter*ncell*namom*nsmom 双精度数)。我以两种不同的方式做到了这一点:
- 多维标准数组“simple_array(egmax,niter,...,)”
- 我提供的代码中定义的嵌套派生数据结构“fancy_array”。
我使用编译代码
ifort -g -o test.exe file.f90
我在 valgrind 中运行它并比较了 simple_array 和 fancy_array 的内存消耗。simple_array 按预期使用大约 300Mb,而 fancy_array 使用 3Gb(10 倍),即使它存储了相同数量的实数。因此,它也应该只消耗 300Mb。
运行一个更简单的测试用例,其中派生类型只有一层深,例如
type level_1
real(kind=d_t),allocatable :: subarray(:)
end type
type array
type(level_1),allocatable :: lev_1(:)
end type
完全消耗我期望的内存量。它不会消耗 10 倍的内存。有没有人观察到类似的行为或有任何线索为什么会发生这种情况?对于所描述的行为,我唯一的想法是,fancy_array 分配了不连续的内存,fortran 需要以某种方式跟踪它,因此增加了内存消耗。我将不胜感激任何输入或类似的意见。
谢谢你的帮助。
塞巴斯蒂安