【问题标题】:Memory allocation when a pointer is assigned分配指针时的内存分配
【发布时间】:2022-09-24 21:15:31
【问题描述】:

我试图在我的代码中避免内存分配和本地复制。下面是一个小例子:

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

据我了解,子程序test_copy 应该产生一个本地副本,而子程序test_assoc 应该只分配一个指向某个现有对象的指针。但是,使用 caliper 进行内存分析会导致:

$ ./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

看起来很奇怪的是,无论参数nb 的值如何,Caliper 都显示了完全相同的内存分配量。我是否使用正确的工具以正确的方式跟踪内存分配和本地副本?

使用 gfortran 11.2.0 和 Caliper 2.8.0 进行测试。

  • test_copy() 中,local(确实)纯粹是本地的,它的内容从未被使用过。编译器不分配就直接扔掉也不是不可能的。尝试在例程末尾添加local 的任何元素的write(*,*),以强制编译器分配它。
  • @PierU 子程序 test_copytest_assoc 都改变了 local%n 和 local%d 的值。添加write(*,*) local%n(nb), local%d(nb) 对caliper 报告中打印的分配内存没有影响。

标签: memory memory-management fortran


【解决方案1】:

local 对象只是一个简单的小标量,尽管它包含一个数组组件,并且很可能被放置在堆栈上。

堆栈是固定大小的内存的预分配部分。堆栈“分配”实际上只是堆栈指针的值的变化,它只是一个整数值。操作系统不会进行实际的内存分配。进程占用的内存不会发生变化。

【讨论】:

  • local 对象不包含数组 local%nlocal%d ?我的理解如下:语句local=abclocal%nlocal%d 内创建abc%nabc%d 的副本。编辑:我正在尝试测量这个副本。
猜你喜欢
  • 2021-06-22
  • 2015-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-21
  • 2014-01-31
  • 2019-01-10
  • 1970-01-01
相关资源
最近更新 更多