Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 当传递私有变量时,而不是在并行区域内声明变量时,Openmp SEGFULT_C_Parallel Processing_Openmp - Fatal编程技术网

C 当传递私有变量时,而不是在并行区域内声明变量时,Openmp SEGFULT

C 当传递私有变量时,而不是在并行区域内声明变量时,Openmp SEGFULT,c,parallel-processing,openmp,C,Parallel Processing,Openmp,标题说明了一切。当我在并行区域外声明数组x并将其作为私有变量传递给线程时,我得到一个segfault。 当我在并行区域内声明变量时,一切正常。 我感兴趣的是将变量作为private传递,而不是声明它,因此我需要帮助来调试这个问题。 下面是它的样子: //Case1 - doesn't work (segfault) x = (double *) malloc (solution * sizeof(double)); #pragma omp parallel for private(x) for.

标题说明了一切。当我在并行区域外声明数组x并将其作为私有变量传递给线程时,我得到一个segfault。 当我在并行区域内声明变量时,一切正常。 我感兴趣的是将变量作为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 
更新

尽管约翰提出了建议,我还是有过错。这是一段实际的代码。我实际上在使用CPLEX优化库。我还尝试使用memcpy进行私有变量分配

#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
}
#专用(i)共享(lp、env)的pragma omp并行

对于(i=0;i您关于一个代码工作而另一个代码不工作的断言充其量是近似的。事实上,两个代码都没有按照所示成功编译。几乎可以肯定的是,在一种情况下报告的错误行为还取决于变量
x
在并行部分中的使用方式

如上所述,如果工作代码和非工作代码之间的唯一区别是
x
声明和赋值的位置,如图所示,那么在并行区域外赋值
x
的版本出现故障也就不足为奇了。OpenMP规范描述了每个thr范围内的私有
x
sead以这种方式在案例1的平行区域运行:

为构造分配具有自动存储持续时间的相同类型的新列表项。[…]新列表项已初始化,或具有未定义的初始值,就好像它是在没有初始值设定项的情况下本地声明的一样。

(摘自OpenMP 4.5、2.15.3.3;增加了重点)

也就是说,并行循环内的本地
x
s不是以循环外(单独的)
x
的值开始的。它们的初始值是不确定的(对于没有初始值设定项的自动声明对象,按C).使用该初始值会产生未定义的行为,这很可能表现为分段错误

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

x = (double *) malloc (solution * sizeof(double));
#pragma omp parallel for
for (double *y = x; ...
(默认情况下,
x
是共享的,
y
是私有的)。在这种情况下,您希望每个线程都有一个指向相同共享空间的私有指针


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

您关于一个代码工作而另一个代码不工作的断言充其量也只是近似值。事实上,两个代码都没有按所示成功编译。看起来几乎可以肯定的是,在一个案例中报告的不当行为也取决于变量
x
在平行部分中的使用方式

如上所述,如果工作代码和非工作代码之间的唯一区别是
x
声明和赋值的位置,如图所示,那么在并行区域外赋值
x
的版本出现故障也就不足为奇了。OpenMP规范描述了每个thr范围内的私有
x
sead以这种方式在案例1的平行区域运行:

为构造分配具有自动存储持续时间的相同类型的新列表项。[…]新列表项已初始化,或具有未定义的初始值,就好像它是在没有初始值设定项的情况下本地声明的一样。

(摘自OpenMP 4.5、2.15.3.3;增加了重点)

也就是说,并行循环内的本地
x
s不是以循环外(单独的)
x
的值开始的。它们的初始值是不确定的(对于没有初始值设定项的自动声明对象,按C).使用该初始值会产生未定义的行为,这很可能表现为分段错误

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

x = (double *) malloc (solution * sizeof(double));
#pragma omp parallel for
for (double *y = x; ...
(默认情况下,
x
是共享的,
y
是私有的)。在这种情况下,您希望每个线程都有一个指向相同共享空间的私有指针


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

完全不清楚您实际打算做什么,请提供一个。在第一种情况下,您将指针变量设为私有。这意味着,每个线程接收指针本身的私有未初始化副本。这不会创建指针指向的对象的私有副本。完全不清楚您实际打算做什么,请提供一个。在第一种情况下,您将指针变量设为私有。这意味着,每个线程接收指针的私有未初始化副本呃,它本身。这不会创建指向的内容的私有副本。