我刚刚注意到以下代码不能在OpenMP中编译(在GCC 4.5.1下):
struct job {
unsigned busy_children;
};
job* j = allocateJob(…);
// …
#pragma omp flush(j->busy_children)
编译器抱怨参数列表中的表达式要刷新,根据OpenMP规范,这是正确的:flush
希望参数是“id- ->
”列表,这基本上意味着只允许(限定)id,不允许表达式。
此外,规范中还提到了flush
和指针:
如果列表中存在指针,则刷新指针本身,而不是指针所引用的内存块。
当然了。然而,由于OpenMP也不允许我取消对指针的引用,所以我基本上不能刷新指针对象(指针目标)。
-那么引用又如何呢?规范没有提到它们,但我不确定以下内容是否符合,并且实际上会刷新指针对象。
unsigned& busy_children = j->busy_children;
#pragma omp flush(busy_children)
这能保证有效吗?
如果不是,我如何刷新指针对象?
发布于 2011-01-28 04:56:44
flush指令让OpenMP ARB头疼了很长一段时间。因此,人们一直在谈论完全移除它--尽管这会带来其他问题。使用flush(list),是非常困难的,即使是OpenMP专家也很难做到正确。它的问题是,它的定义方式可以通过编译器在您的代码中移动。这意味着你应该远离使用flush(list)。
至于你关于能够刷新指针对象的问题,只有一种方法可以做到这一点,那就是使用flush (不带列表)。这将刷新整个线程环境,因此,编译器不能移动它。这看起来很“笨拙”,但实际上编译器很擅长在没有列表的情况下使用flush时刷新必要的内容。
发布于 2011-01-28 04:57:00
OpenMP规范并没有直接说明变量的类型,但是MSDN说“在flush指令中指定的变量不能有引用类型”。这让我认为这并不能保证工作。变量列表为空的flush
指令应该刷新所有内存,这样您就可以安全地使用它了。
发布于 2018-06-21 07:27:57
不能刷新已取消引用的指针的原因是,只有硬件寄存器中的值才需要刷新。在OpenMP下,不需要刷新不在硬件寄存器中(例如,在缓存或内存中)的内容,因为OpenMP假定有一个连贯的缓存,保证当相同的地址被解除引用时,所有线程将始终看到相同的值。硬件协议保证了高速缓存的一致性,使得多个本地高速缓存的行为类似于一个共享的全局高速缓存。
https://stackoverflow.com/questions/4821491
复制相似问题