【发布时间】: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_copy和test_assoc都改变了 local%n 和 local%d 的值。添加write(*,*) local%n(nb), local%d(nb)对caliper 报告中打印的分配内存没有影响。
标签: memory memory-management fortran