繁体   English   中英

OpenMP和C:这个操作必须是原子的吗?

[英]OpenMP and C: Must this operation be made atomic?

假设我们根据以下类型声明有几个数组

bool B[ N ];
Bar Foo[ M ];
int B_of_Foo[ M ]; // 0 <= B_of_Foo[m] < N

BFoo可以包含任意值(取决于上下文),而B_of_Foo包含的条目限于0N-1之间的索引。 我们来看看下面的代码

bool repeat = true

while( repeat ) {

    repeat = false;

    for( int m = 0; m < M; m++ ) {
      if( complicated_condition( Foo[m] ) {
        B [ B_of_Foo[ m ] ] = true
        repeat |= true;
      }
    }

}

complicated_condition为真,如果Bs的一些AND或OR值是真实的,但B[ B_of_Foo[ m ] ]是假的。 保证在顺序执行时完成此代码。 我想将其与OpenMP并行化。 可以通过还原来处理可变重复。 我想知道是否更新

B [ B_of_Foo[ m ] ] = true

然后必须标记为原子操作。

我认为任何并发或重复的更新都会产生相同的结果。 即使一个线程使用过时版本的B[ B_of_Foo[ m ] ]检查B[ B_of_Foo[ m ] ] ,其后续的写操作也不会改变B的那个条目,即使重复while循环而没有更新B,代码也是稳定的。

是的, B [ B_of_Foo[ m ] ]的更新需要是原子的(或以其他方式序列化),因为多个线程写入同一个变量的结果是未指定的, 即使它们写的是相同的值。 从OpenMP 3标准的1.4.1节(内存模型):

如果多个线程在没有同步的情况下写入同一存储器单元,包括由于如上所述的原子性考虑而导致的情况,则发生数据争用。 类似地,如果至少一个线程从存储器单元读取并且至少一个线程在没有同步的情况下写入同一存储器单元,包括由于如上所述的原子性考虑而导致的情况,则发生数据竞争。 如果发生数据争用,则未指定程序的结果。

在开始时,大多数人都想到了一种内存模型,其中存在某种类型的顺序一致性保证 - 比如在POSIX文件系统中 - 如果发生两个并发写操作,它们的行为就像它们被随机序列化一样“获胜” 。 在教授数据竞赛时,大多数使用的例子都没有用。 但是没有这样的东西得到保证,原则上结果可能是完全的胡言乱语。 (它是否在您最喜欢的架构上实际发生是一个不同的问题。在这里,您的值是单个字节,我不得不认为您在x86的大多数实现中都没问题。但没有任何保证。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM