有没有一种简单的方法来为并行调用准备Fortran代码

时间:2014-03-13 14:30:40

标签: memory-management parallel-processing fortran openmp

我想使用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总是从堆中分配,所以我不想将它用于所有局部变量 - 对吗?

1 个答案:

答案 0 :(得分:3)

标准没有谈论静态内存,堆或堆栈等任何内容。如果使用recursive或强制它的编译器选项,那么您可以确保子例程的每个副本都使用它们自己的变量副本,除非它们是save。它们通常在堆栈中。如果不使用recursive,编译器可以自由使用静态内存。大多数情况下它使用堆栈,但你不能依赖它。 BTW,gfortran编译器使用-fopenmp自动隐含-frecursive

小心!显式初始化的每个变量都是save隐式!

real :: ivar = 1

就是这样一个例子。使用DATA初始化具有相同的效果。除非您删除初始化或使用threadprivate

,否则此变量不是线程安全的

对于动态分配,当然要使用allocate。这很安全。每个openmp线程将分配它自己的变量和数组。

threadprivate指令确实很有用,正如您自己发现的那样。我不确定你是否可以保证它会使用堆栈或堆,但堆更有可能因为它们必须在整个执行过程中保持在范围内。

不仅common对应于C全局变量。模块变量也是如此。它们也是save隐含的。