Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29267 Discussions

strange memory occupier of allocatable array in custom type in Fortran

Jovan_Z_
Beginner
664 Views

I wanna create an allocatable array in custom type as follows:

  1. type cell
  2.    integer(4) :: fn
  3.    integer(4), dimension(:), allocatable :: nd
  4. end type cell
  5. type(cell), dimension(:), allocatable :: elem
  6. allocate(elem(10000))

There is memory occupier ten times more than 10000*4 Bytes before allocating array nd, why?

I thought a custom type might not contains any uncertain array, and modified the code as follows:

  1. type cell
  2.    integer(4) :: fn
  3.    integer(4), pointer :: nd(:)
  4. end type cell
  5. type(cell), dimension(:), allocatable :: elem
  6. allocate(elem(10000))
  7. do i=1,10000
  8.    elem(i)%nd=>cnode(j:j+7)
  9. end do

 where cnode is a target array. The same situation happens, i.g. the memory occupier is  ten times

more than (10000*4+10000*8*4), and why? What should I do to change this?

0 Kudos
5 Replies
jimdempseyatthecove
Honored Contributor III
664 Views

You are allocating an array of cell, not an array of integer(4).

The => must have a pointer on the left side, yours has an allocatable array.

If you were to re-type nd as pointer, the cell would have

integer(4) for fn
+ and pointer with array descriptor (size varies depending on platform)

Jim Dempsey

0 Kudos
Jovan_Z_
Beginner
664 Views

Yes, I found the pointer with array descriptor occupying memory tens of times more than 4 bytes, which was although announced as integer pointer.

jimdempseyatthecove wrote:

You are allocating an array of cell, not an array of integer(4).

The => must have a pointer on the left side, yours has an allocatable array.

If you were to re-type nd as pointer, the cell would have

integer(4) for fn
+ and pointer with array descriptor (size varies depending on platform)

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
664 Views

If your cell array is sparsely filled, and you have an interest in conserving memory then consider

type nd_t
  integer(4), dimension(:), allocatable :: nd
end type nd_t

type cell
  integer(4) :: fn
  type(nd_t), pointer :: p_nd
end type cell

Caution, should your array be more than sparsely filled, then this will consume additional memory.

Jim Dempsey

0 Kudos
Jovan_Z_
Beginner
664 Views

What if the cell array is fully filled? I use allocatable array to store all data I need without any blank array element.

For this situation, the large memory occupier of pointer is ievitable, right?

0 Kudos
jimdempseyatthecove
Honored Contributor III
664 Views

You will note that I preface my suggestion with "If your cell array is sparsely filled". When not sparsely filled, you would not use the extra indirection. To determine the effectiveness of the indirection:

IA32:

    4 + 32 bytes per cell (1D array) + allocation bytes + heap header
vs
    4 + 4 bytes per cell +  32 bytes per cell having allocation  + heap header

Intel64

    4 + 64 bytes per cell (1D array) + allocation bytes + heap header
vs
    4 + 8 bytes per cell +  64 bytes per cell having allocation  + heap header

Potentially (rough approximation) when your percent of cells allocated falls below 85%, you'd save memory.

Alternative strategy:

You illustrated: elem(i)%nd=>cnode(j:j+7), if the target of the pointer is always a slice of cnode, then your user defined type could contain:

  a type field of number of bytes necessary for your list of types (1:4 bytes)
  a length field of  number of bytes necessary for your largest type (1:4 bytes)
  a starting index into cnode (2:4 bytes)

Each cell entry would then be between 4 and 12 bytes depending on your requirements.

Jim Dempsey

0 Kudos
Reply