c - 传递私有(private)变量时出现 Openmp 段错误,但在并行区域内声明变量时不会出现

标签 c parallel-processing openmp

标题说明了一切。当我在并行区域之外声明数组 x 并将其作为私有(private)变量传递给线程时,我得到了一个段错误。 当我在并行区域内声明变量时,一切正常。 我有兴趣将变量作为私有(private)变量传递而不是声明它,因此我需要帮助来调试问题。 这是它的样子:

//Case1 - doesn't work (segfault)
x = (double *) malloc (solution * sizeof(double));
#pragma omp parallel for private(x)
for...

//Case2 - works
#pragma omp parallel for 
for...
    x = (double *) malloc (solution * sizeof(double));

我正在使用 72 个线程并且我已将 KMP_STACKSIZE 设置为 1m 以及

ulimit -s unlimited 

更新

尽管有 John 的建议,我仍然遇到了段错误。这是实际的代码。我实际上正在使用 CPLEX 优化库。我还尝试使用 memcpy 进行私有(private)变量分配。

#pragma omp parallel for private(i) shared(lp,env)
for(i=0;i<n;i++){
    CPXENVptr envi =env;
    CPXLPptr    lpi = lp
    CPXLpopt(envi,lpi);//this is where the segfault happens
}

值得注意的是 CPLXLpopt 命令改变了 envi 和 lpi 变量的大小/ 您是否推荐任何用于 openmp 的调试器?

最佳答案

您关于一个代码有效而另一个无效的断言充其量只是近似的。事实上,这两种 代码甚至都可以像展示的那样成功编译。几乎可以肯定的是,在一个案例中报告的不当行为还取决于并行部分中变量 x 的使用方式。

话虽如此,如果工作代码和非工作代码之间的唯一区别是 x 的声明和赋值的位置,如图所示,那么赋值的版本就不足为奇了x 在并行区域之外的段错误。 OpenMP 规范以这种方式描述在案例 1 的并行区域中运行的每个线程范围内的私有(private) x:

A new list item of the same type, with automatic storage duration, is allocated for the construct. [...] The new list item is initialized, or has an undefined initial value, as if it had been locally declared without an initializer.

(来自 OpenMP 4.5、2.15.3.3;已强调)

也就是说,并行循环内的局部 x 不以循环外的(单独的)x 的值开头。它们的初始值是不确定的(根据 C,对于没有初始化器声明的自动对象)。使用该初始值会产生未定义的行为,这很可能表现为段错误。

您可以通过允许共享 x 并在并行部分使用不同的私有(private)变量(从共享的 x 初始化)来解决这个问题。像这样的东西,例如:

x = (double *) malloc (solution * sizeof(double));
#pragma omp parallel for
for (double *y = x; ...

(默认情况下,x 是共享的,y 是私有(private)的)。这适用于您希望每个线程都有一个指向同一共享空间的私有(private)指针的场景。

但是请注意,无论如何,x 指向的内存都是共享的。如果您希望每个线程都有自己的、独立的、动态分配的空间,那么每个线程都需要自己分配这样的空间(并随后释放该空间)。即使在那种情况下,分配的空间在技术上是共享的,但如果线程不发布任何指向它们分配的空间的指针,那么其他线程将无法访问它们。

关于c - 传递私有(private)变量时出现 Openmp 段错误,但在并行区域内声明变量时不会出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41573020/

相关文章:

multithreading - 多线程环境中的Malloc性能

c - C 中的嵌套链表

c - 识别 connect( ) 的问题

JAVA - 多线程Mergesort的排序速度

c - OpenMP 花费的时间比预期的要长

r - "user","system"和 "elapsed"次在 R 中是什么意思

c - 平行区域上的矩阵元素之和导致 OpenMP 上的错误答案

c++ - 在 Openmp (C++) 中销毁线程

c - 带减法的整数溢出

c - 使用 MPI 接收数组