在OpenMP中定义一个struct指针为threadprivate



从C中调用Fortran代码,然后调用其他C代码。为了调用C代码的最后一点,我需要有两个指向EarthModel结构体和我定义的SurveyGeometry结构体的全局指针。我已经尝试在calcGreen.c中并行化下面的for循环,但是超过1个线程(程序分段错误)都没有成功。

我需要每个线程都有自己的指针指向不同的EarthModels和SurveyGeometrys,同时保持全局定义。我尝试使用omp threadprivate指令给每个线程自己的结构指针,它可以分配和释放并维护线程级别的全局定义。我还读到创建线程的默认堆栈是2M,所以我尝试通过设置导出OMP_STACKSIZE=512M(或更高)的环境变量来为线程提供更多内存,但是段错误仍然存在。

shared.h

extern EarthModel *g_em;
extern SurveyGeometry *g_sg;
#pragma omp thradprivate(g_em, g_sg)

util.h

#include "shared.h"
EarthModel *g_em;
SurveyGeometry *g_sg;

calcGreen.c

#include "util.h"
...
omp_set_num_threads(2);
#pragma omp parallel for schedule(dynamic,1)
for(int ii=0; ii<nseg; ++ii){
  for(int jj=0; jj<nseg; ++jj){
    ...
    // code to allocate and initialize g_sg and g_em
    g_sg = initSG();
    g_em = initEM();
    // code to pass through to Fortran and execute C function on g_sg and g_em
    // code to free g_sg and g_em
    freeSG(g_sg);
    freeEM(g_em);
    ...
  }
}
...

编辑:或者,是否有一种方法可以从第一个C函数中获得g_sg和g_em结构体,其中分配并设置为Fortran以线程安全的方式调用的C函数,而不使用全局变量?

不完全确定为什么会这样,但是正确拼写"threadprivate"并将#pragma omp threadprivate指令移动到util.h似乎已经成功了。第一个不足为奇,但第二个对我来说并不直观。谢谢你的帮助。

如果Harald的评论还不能解决问题,以下是一些建议:

1)如果允许更改calcGreen.c的源代码,并且如果每个线程在通过调用initSG()和initEM()(重新)初始化(重新)分配和(重新)初始化之前不使用指针,我会将它们声明为内部for循环中的局部变量。

2) initSG(), initEM(), freeSG()和freeEM()的实现是线程安全的和可重入的吗?

最新更新