我想使用OpenMP在C ++程序中并行解决多个大型ODE系统。出于某些原因,我需要使用ODE求解器,我只能找到Fortran 90子程序,并且代码太大而不能简单地将其转换为C.
我知道Fortran广泛使用静态内存,因此我必须为并行调用填充代码;但我对语言并不熟悉,所以:
第二个问题归结为:Fortran如何以及何时为变量分配和释放内存以及(如何)从函数参数中重用内存?
到目前为止,我已经发现COMMON
部分对应于C中的全局变量,但可以使用Fortran的OpenMP指令!$OMP THREADPRIVATE(/…/)
进行线程局部化。它是否正确?其他局部变量怎么样?它们也是静态分配的,对吧?告诉Fortran动态分配它们的最简单方法是什么?我应该使用ALLOCATE
语句,还是使用RECURSIVE
关键字。 gfortran的-frecursive
,帮助,或者是否有某种方法可以从C ++传递大量内存并让Fortran将其用于所有变量? (EQUIVALENCE
?)OpenMP' s THREADPRIVATE
总是从堆中分配,所以我不想将它用于所有局部变量 - 对吗?
答案 0 :(得分:3)
标准没有谈论静态内存,堆或堆栈等任何内容。如果使用recursive
或强制它的编译器选项,那么您可以确保子例程的每个副本都使用它们自己的变量副本,除非它们是save
。它们通常在堆栈中。如果不使用recursive
,编译器可以自由使用静态内存。大多数情况下它使用堆栈,但你不能依赖它。 BTW,gfortran
编译器使用-fopenmp
自动隐含-frecursive
。
小心!显式初始化的每个变量都是save
隐式!
real :: ivar = 1
就是这样一个例子。使用DATA
初始化具有相同的效果。除非您删除初始化或使用threadprivate
。
对于动态分配,当然要使用allocate
。这很安全。每个openmp线程将分配它自己的变量和数组。
threadprivate
指令确实很有用,正如您自己发现的那样。我不确定你是否可以保证它会使用堆栈或堆,但堆更有可能因为它们必须在整个执行过程中保持在范围内。
不仅common
对应于C全局变量。模块变量也是如此。它们也是save
隐含的。