c - 何时为 OpenMP 使用私有(private)和共享变量

标签 c openmp

我的假设是,如果您有一个要使用 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 隐含 sharedx,z,y 隐含 private )

显式的数据共享子句会产生冗余,并且除非您确切知道自己在做什么,否则也可能很危险:私有(private)变量未初始化,即使它们在并行区域之外具有有效值,并且在平行区?因此我强烈推荐使用隐式默认方法,除非高级使用需要。

1 您的代码实际上是错误的,因为多个线程将不同的值写入同一个内存位置 - 甚至同时从它们读取。但我不打算详细说明,因为你提到这是一个例子。尽管如此,shared 很可能是你想要的这样一个循环。

关于c - 何时为 OpenMP 使用私有(private)和共享变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50673809/

相关文章:

c - 在 Linux 中为 NTFS 执行 ls 命令

c++ - Openmp:无法正确计算并行 for 循环内的作业状态

c - 如何在没有竞争条件和错误共享的情况下使用 OpenMP 并行化此函数?

c++ - 与 zheevr 的 OpenMP C++ 数据竞赛

iphone - C 结构的初始化如何在 iOS Objective-C 中工作?

c - MakeFile 不编译和构建 .o 文件

c - 字计数器 'forgetting' 关于已保存的字

c++ - 如何在不指定 C++ 中的所有参数的情况下声明程序的 main() 入口点?

fortran - OpenMP 和 gfortran 中的嵌套并行区域

c++ - OpenMP、C++ 和迭代器