关于我们应该在何处分配阵列的建议或最佳实践是什么?
例如,如果我有一个(我的简化版本)程序,我将在主程序中分配输出变量(感兴趣的变量) . 这个主程序调用子程序 foo
,然后调用子程序 foo2
,谁进行实际计算 . 我的问题是应该在哪里进行分配的最佳/推荐做法 .
-
如果
foo2
进行实际计算,是否应该分配数组? -
如果
foo
调用foo2
,foo
应该分配数组而foo2
只进行计算吗? -
我应该编写一个新的函数/子程序来分配数组吗?
-
或者最好在主程序上分配并将数组作为假定形状传递?
如果它很重要,我有一个名为global的模块,它包含主程序的派生类型,以及代码的主要参数,例如每个数组的大小( Ni
, Nj
,容差等)
program main
use global
implicit none
type(myVar_) :: ans
Ni = 10
Nj = 20
if (allocated(ans%P)) deallocate(ans%P)
allocate(ans%P(1:Ni, 1:Nj))
call foo(ans)
print *, P
end program main
module global
integer, parameter :: dp=kind(0.d0)
integer :: Ni, Nj
type myVar_
real(dp), allocatable :: P(:,:)
end type myVar_
end module global
subroutine foo(myVar)
use global
implicit none
type(myVar_) :: myVar
call foo2(myVar%P)
end subroutine
subroutine foo2(P)
use global
implicit none
real(dp), intent(inout) :: P(:,:)
! do calculations for P
end subroutine foo2
什么是
1 回答
为了性能原因,避免在低级子程序中进行分配和功能确实是一种好的做法 . 从[1]中可以看出,简单的加法需要大约1-3个CPU周期,分配和释放对(“小”数组)可能需要200到500个CPU周期 .
我建议你使用“工作”变量作为输入编写一个子程序,并可能在适当的位置操作(即用结果覆盖输入),例如:
您可以创建一个包装函数,以便于分配:
当性能不重要时,可以调用
convenient_subroutine
,但是否则调用do_computation
尝试在循环迭代之间和不同的其他子例程之间共享工作数组 .[1] http://ithare.com/infographics-operation-costs-in-cpu-clock-cycles/