我想使用 OpenMP 在 C++ 程序中并行求解多个大型 ODE 系统。由于某些原因,我需要使用 ODE 求解器,但我只能找到 Fortran 90 子例程,而且代码太大,无法简单地将其转换为 C。
我知道 Fortran 广泛使用静态内存,因此我必须为并行调用准备代码;但我不太熟悉这门语言,所以:
- 我的问题有标准(自动)解决方案吗?
- 我需要修改代码的哪些部分?
第二个问题归结为:Fortran 如何以及何时为变量分配和释放内存,以及(如何)重用函数参数中的内存?
到目前为止,我已经发现了COMMON
部分对应于 C 中的全局变量,但可以使用 Fortran 的 OpenMP 指令使其成为线程局部变量!$OMP THREADPRIVATE(/…/)
。它是否正确?其他局部变量呢?它们也是静态分配的,对吗?告诉 Fortran 动态分配它们的最简单方法是什么?我应该使用ALLOCATE
声明,或者RECURSIVE
关键字,分别。 gfortran 的-frecursive
,帮助,或者有什么方法可以从 C++ 传递一大块内存并让 Fortran 将其用于所有变量? (EQUIVALENCE
?) OpenMP 的THREADPRIVATE
总是从堆分配,所以我不想将它用于所有局部变量 - 对吗?
该标准没有讨论静态内存、堆或堆栈之类的内容。如果你使用recursive
或者强制它的编译器选项,那么您可以确定子例程的每个副本都使用自己的变量副本,除非它们是save
。它们通常位于堆栈上。如果你不使用recursive
编译器可以自由使用静态内存。大多数情况下它使用堆栈,但你不能依赖它。顺便说一句,在gfortran
编译器使用-fopenmp
暗示-frecursive
自动地。
谨防!每个显式初始化的变量都是save
隐含地!
real :: ivar = 1
就是这样一个例子。初始化使用DATA
具有相同的效果。该变量将不是线程安全的,除非您删除初始化或使用threadprivate
.
对于动态分配,请使用allocate
当然。这是安全的。每个 openmp 线程都会分配它自己的变量和数组。
The threadprivate
指令确实很有用,正如您自己发现的那样。我不确定您是否可以保证它将使用堆栈或堆,但堆更有可能,因为它们必须在整个执行过程中保留在范围内。
不仅common
对应于 C 全局变量。模块变量也是如此。他们也是save
隐含地。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)