我用 Fortran 进行了科学模拟。在其中,我需要在开头“一次”计算一个大数组(例如 10^5 个元素,大小已知/可以在编写代码时预设),然后需要共享/访问/读取该数组进入很多次(基本上每一步,所以可能数百万次)。
与其他子例程共享此类数组的推荐方式是什么?鉴于我希望创建大数组的代码成为它自己的实体。
假设存在情况 1,其中:
有情况 2,其中:
最后是情况 3,与情况 2 完全相同,只是数组可以作为数据语句在代码中进行物理预设/写入。
每种情况下的最佳实践是什么,以及优化速度/最小化可能的运行时间损失?
编辑:这是我目前的解决方案。有一个如下形式的模块
module big_array
parameter (nbigarray=10**5)
real my_by_array(nbigarray)
contains
subroutine init_big_array(arglist)
*[here some code populating / creating *my_big_array*]*
return
end
end module
在程序开始时运行
init_big_array
一次,并在需要 my_big_array
的地方使用该模块。
这是动态内存管理的介绍,它允许将
array
暴露给子程序。
module foo
implicit none ! Always include this statement
!
! Make everything private and only expose those entities
! that are needed.
!
private
public array, init_array, destroy_array
integer, allocatable :: array(:)
contains
!
! Destroy array
!
subroutine destroy_array
if (allocated(array)) then
deallocate(array)
end if
end subroutine
subroutine init_array(n)
integer, intent(in) :: n
if (n < 0) then
!
! Could implement a fallback. Perhaps,
! allocate a zero-sized array.
!
write(*,'(A)') 'init_array: memory allocation issue'
stop
end if
!
! Check if array is allocated and the requested size
! differs from the current allocated size.
!
if (allocated(array)) then
if (size(array) /= n) then
call destroy_array
allocate(array(n))
end if
else
allocate(array(n))
end if
end subroutine
end module foo
program main
use foo, only : array, init_array
implicit none
integer m
!
! Perhaps, "read(*,*) m" to allow user to size
! memory appropriately.
!
m = 100
call init_array(m)
call bar
end program
subroutine bar
use foo, only : array
implicit none
if (allocated(array) then
print *, size(array)
else
write(*,'(A)') 'whoops'
end if
end subroutine bar