简体   繁体   English

OpenMP中的同步

[英]Synchronization in OpenMP

I am trying to implement a parallel algorithm with OpenMP. 我正在尝试使用OpenMP实现并行算法。 In principle I should have many threads writing and reading different components of a shared vector in an ashyncronous way. 原则上,我应该有许多线程以异步方式写入和读取共享向量的不同组成部分。 There is a FOR loop in which the threads cycle and when a thread is in, let's say, row A of the loop it writes on a random component of the shared vector, while when it is in row B it reads a random component of the same shared vector. 有一个FOR循环,线程在其中循环,当线程进入循环的A行时,它写在共享向量的随机分量上,而当它在B行中时,它读到共享向量的随机分量。相同的共享向量。 It may happen that a thread would try to read a component of the shared vector while this component is written by another thread. 可能发生线程试图读取共享向量的一个组件而另一个线程写入该组件的情况。 How to avoid inconsistency? 如何避免不一致?

I read about locks and critical sections, but I think this is not the solution. 我阅读了有关锁和关键部分的文章,但我认为这不是解决方案。 For example, I can set a lock around row A in which the threads write in the shared vector, but does this prevent inconsistency if at the same time a thread in row B is trying to read that component? 例如,我可以在行A周围设置一个锁,线程在该行中写入共享矢量,但是如果同时行B中的线程正在尝试读取该组件,这是否可以防止不一致?

If the vector modifications are very simple single-value assignment operations and are not actually function calls, what you need are probably atomic reads and writes. 如果向量修改是非常简单的单值赋值操作,而不是实际的函数调用,则您可能需要的是原子读取和写入。 With atomic operations, a read from an array element that is simultaneously being written to will either return the new value or the previous value; 对于原子操作,从同时被写入的数组元素读取将返回新值或先前值; it will never return some kind of a bit mash of the old and the new value. 它永远不会返回旧值和新值的某种混搭。 OpenMP provides the atomic construct for that purpose. OpenMP为此提供了atomic构造。 On certain architectures, including x86, atomics are far more lightweight than critical sections. 在某些架构(包括x86)上,原子比关键部分轻得多。

With more complex modifications you have to use critical sections. 对于更复杂的修改,您必须使用关键部分。 Those could be either named or anonymous. 这些名称可以是匿名的。 The latter are created using 后者是使用创建的

#pragma omp critical
code block

Anonymous critical sections all map to the same synchronisation object, no matter what the position of the construct in the source code, therefore it is possible for unrelated code sections to get synchronised with all possible ill effects, like performance degradation or even unexpected deadlocks. 无论源代码中构造的位置如何,匿名关键节都映射到同一同步对象,因此,不相关的代码节有可能与所有可能的不良影响(例如性能下降甚至意外的死锁)同步。 That's why it is advisable to always use named critical sections. 因此,建议始终使用命名的关键部分。 For example, the following two code segments will not get synchronised: 例如,以下两个代码段将不会同步:

// -- thread i --                  // -- thread j --
...                                ...
#pragma omp critical(foo)  <       #pragma omp critical(foo)
do_something();            <       do_something;
...                                ...
#pragma omp critical(bar)          #pragma omp critical(bar)  <
do_something_else();               do_something_else();       <
...                                ...

(the code currently being executing by each thread is marked with < ) (每个线程当前正在执行的代码用<标记)

Note that critical sections bind to all threads of the program, without regard to the team to which the threads belong. 请注意,关键部分绑定到程序的所有线程,而与线程所属的团队无关。 It means that even code that executes in different parallel regions (a situation that mainly arises when nested parallelism is used) gets synchronised. 这意味着即使在不同的并行区域中执行的代码(这种情况主要发生在使用嵌套并行机制时)也将同步。

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

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