使用静态变量在子例程中存储状态是一种好习惯吗?

时间:2016-06-29 18:24:17

标签: fortran fortran90

使用静态变量在子程序中存储状态是一种好习惯吗?我记得以下内容:

subroutine somesub()
logical, save :: first_call = .true.


if (first_call) then
! do some stuff

first_call = .false.
end if

! ... perform standard work

end subroutine somesub

“某些东西”的例子包括:

  1. 分配工作数组。这可能最好由自动数组完成。
  2. 初始化需要某种运行时评估的物理/数学常量。一个很好的例子是pi = datan(1.0)*4d0
  3. 从名单或文本文件中读取一些参数和物理内容。
  4. 根据this question,在使用多线程的实例中,使用静态变量来存储这种状态是不受欢迎的。这是典型的fortran物理仿真代码中openmp或mpi的问题吗?

    您建议使用哪种替代方法来处理特定子程序特有的物理常量和用户可修改参数?

1 个答案:

答案 0 :(得分:1)

这太长,太有启发性,无法发表评论,所以我把它作为答案。它详细阐述了弗拉基米尔的评论。

如果子程序足够具体,可以拥有自己的一组参数,而这些参数不能被程序的任何其他部分访问,那么为该子程序创建一个模块。将子程序的参数添加为模块的私有实体,添加子程序本身(仅标准工作)并添加初始化子程序,最后添加终结子程序。

确保程序调用初始化子例程并最终调用finalization子例程。对我而言,这是一种优雅的做法,适用于您将来可能会遇到的一般情况。例如,如果需要保存子例程的状态或释放一些系统资源,则最终确定是最佳位置。

这在MPI环境中非常有效,其中每个实例可能有自己的子例程参数集。只要知道何时调用初始化,openmp也会很方便。

您的模块可能如下所示:

module some_mod
implicit none
    private
    ! declare all the stuff that are private to your module here
    public somesub, init_somesub, finalize_somesub
contains

    subroutine somesub()
        !
        ! perform only the standard work, nothing else
        !
    end subroutine somesub

    subroutine init_somesub()
        !
        ! do only the initialization here
        !
    end subroutine init_somesub

    subroutine finalize_somesub()
        !
        ! do some stuff here to finalize if necessary
        !
    end subroutine finalize_somesub

end module some_mod