我的假设是,如果您有一个要使用 OpenMP 的嵌套循环,则必须将内部循环的循环变量设为私有(private),如下所示。
int x,y,z;
#pragma omp parallel for private(y,z)
for (x=0;x<100;x++)
{
for (y=0;y<100;y++)
{
for (z=0;z<100;z++)
{
a[x+y+z]=a[x]+a[y]+a[z]; //arbitrary code, a is just an arbitrary array
}
}
}
但是,当我在没有
private(y,z)
的情况下运行相同的循环时,它仍然运行良好。那么究竟有哪些情况需要使用private
/shared
?
最佳答案
了解共享和私有(private)之间的区别很重要,而且您似乎做得很好。接下来要学习的是,在并行区域之外声明的变量是隐式 shared
和内部声明的变量是隐式 private
.如果您考虑一下,这是非常有意义的,这样您就可以并且应该通过始终 为自己保存显式声明。尽可能在本地声明变量 .
在您的代码中,这意味着:
#pragma omp parallel for private(y,z)
for (int x=0;x<100;x++)
{
for (int y=0;y<100;y++)
{
for (int z=0;z<100;z++)
{
a[x+y+z]=a[x]+a[y]+a[z]; //arbitrary code, a is just an arbitrary array
}
}
}
这使得对代码的推理变得更加容易——无论是否使用 OpenMP。对于 OpenMP,这意味着默认情况下代码是正确的 1。 (
a
隐含 shared
和 x,z,y
隐含 private
)显式的数据共享子句会产生冗余,并且除非您确切知道自己在做什么,否则也可能很危险:私有(private)变量未初始化,即使它们在并行区域之外具有有效值,并且在平行区?因此我强烈推荐使用隐式默认方法,除非高级使用需要。
1 您的代码实际上是错误的,因为多个线程将不同的值写入同一个内存位置 - 甚至同时从它们读取。但我不打算详细说明,因为你提到这是一个例子。尽管如此,shared 很可能是你想要的这样一个循环。
关于c - 何时为 OpenMP 使用私有(private)和共享变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50673809/