根据OpenMP Memory Model,以下内容不正确:
int *p0 = NULL, *p1 = NULL;
#pragma omp parallel shared(p0,p1)
{
int x;
// THREAD 0 // THREAD 1
p0 = &x; p1 = &x;
*p1 ... *p0 ...
}
我的例子如下所示:
int *p0 = NULL, *p1 = NULL;
#pragma omp parallel shared(p0,p1)
{
int x;
// THREAD 0 // THREAD 1
p0 = &x; p1 = &x;
#pragma omp flush
#pragma omp barrier
*p1 ... *p0 ...
#pragma omp barrier
}
这会不正确吗?我在内存模型中找不到不允许这样做的东西。
我假设我的玩具示例是正确的,就像3.1中的内存模型一样,只要程序员确保它仍然存活,它们就允许任务访问私有变量。鉴于任务可以解开,理论上它们可以在不同的工作线程内执行,因此允许OpenMP线程访问另一个的私有内存。
答案 0 :(得分:1)
这应该有效。刷新同步所有共享变量和屏障保证所有线程的mp环境仍处于活动状态。只要你不在p1s赋值中使用p0,反之亦然,它应该没问题。虽然我无法想象为什么会这样做。也许你可以更多地了解这种结构背后的原因。
由于p0和p1在并行区域之后仍然存在,你可以在那里进行所有分配而没有障碍等。
答案 1 :(得分:1)
一方面认为,这类似于尝试通过将局部变量分配给全局变量,然后读取全局变量来读取您调用的某个函数内的局部变量。
这里的类比是全局变量在多线程中就像一个共享变量,本质上可以访问本应是线程私有的东西(比如只能在函数中看到的局部变量)。
因此,为了回答问题所述,对线程私有内存进行解除引用是完全有效的。 允许使用指针别名(这是两个或多个变量提供对内存中相同位置的访问的位置,在您的情况下,一个是线程专用整数,另一个是共享指针)。
虽然完全有效,但要注意这会导致一些难以检测的竞争条件,因为通常不会使用锁来保护对线程私有变量的访问。