Search code examples
memorymemory-managementfortran

Memory allocation when a pointer is assigned


I am trying to avoid memory allocation and local copy in my code. Below is a small example :

module test

  implicit none

  public

  integer, parameter :: nb = 1000
  type :: info
    integer n(nb)
    double precision d(nb)
  end type info

  type(info), save :: abc
  type(info), target, save :: def

  contains

    subroutine test_copy(inf)

      implicit none

      type(info), optional :: inf
      type(info) :: local

      if (present(inf)) then
         local = inf
      else
         local = abc
      endif

      local%n = 1
      local%d = 1.d0

    end subroutine test_copy

    subroutine test_assoc(inf)

      implicit none

      type(info), target, optional :: inf
      type(info), pointer :: local

      if (present(inf)) then
         local => inf
      else
         local => def
      endif

      local%n = 1
      local%d = 1.d0

    end subroutine test_assoc

end module test

program run

  use test
  use caliper_mod

  implicit none

  type(ConfigManager), save :: mgr

  abc%n = 0
  abc%d = 0.d0
  def%n = 0
  def%d = 0.d0

  ! Init caliper profiling
  mgr = ConfigManager_new()
  call mgr%add("runtime-report(mem.highwatermark,output=stdout)")
  call mgr%start

  ! Call subroutine with copy
  call cali_begin_region("test_copy")
  call test_copy()
  call cali_end_region("test_copy")

  ! Call subroutine with pointer
  call cali_begin_region("test_assoc")
  call test_assoc()
  call cali_end_region("test_assoc")

  ! End caliper profiling
  call mgr%flush()
  call mgr%stop()
  call mgr%delete()

end program run

As far as i understand, the subroutine test_copy should produce a local copy while the subroutine test_assoc should only assign a pointer to some existing object. However, memory profiling with caliper leads to :

$ ./a.out 
Path       Min time/rank Max time/rank Avg time/rank Time %   Allocated MB 
test_assoc      0.000026      0.000026      0.000026 0.493827     0.000021 
test_copy       0.000120      0.000120      0.000120 2.279202     0.000019

What looks odd is that Caliper shows the exact same amount of memory allocated whatever the value of the parameter nb. Am I using the right tool the right way to track memory allocation and local copy ?

Test performed with gfortran 11.2.0 and Caliper 2.8.0.


Solution

  • The local object is just a simple small scalar, albeit containing an array component, and will be very likely placed on the stack.

    A stack is a pre-allocated part of memory of fixed size. Stack "allocation" is actually just a change of value of the stack pointer which is just one integer value. No actual memory allocation from the operating system takes place during stack allocation. There will be no change in the memory the process occupies.