[英]C++ atomic acquire / release operations what it actually means
I was going thru this page and trying to understand Memory model synchronization modes.我正在浏览此页面并试图了解 Memory model 同步模式。 In below example extracted from there:在下面从那里提取的示例中:
-Thread 1- -Thread 2-
y = 1 if (x.load() == 2)
x.store (2); assert (y == 1)
to which states that the store to 'y' happens-before the store to x in thread 1. Is 'y' variable here a normal global variable or is atomic?到哪个声明在线程 1 中存储到“y”之前发生到“x”的存储。这里的“y”变量是普通全局变量还是原子变量?
Further if the load of 'x' in thread 2 gets the results of the store that happened in thread 1, it must all see all operations that happened before the store in thread 1 , even unrelated ones.此外,如果线程 2 中 'x' 的加载获得线程 1 中发生的存储的结果,则它必须全部看到线程 1 中存储之前发生的所有操作,甚至是不相关的操作。
So what it means that x.store() operation would mean that all read / write to memory should have respective memory data values updated?那么 x.store() 操作意味着所有对 memory 的读/写都应该更新相应的 memory 数据值是什么意思?
Then for std::memory_order_relaxed means " no thread can count on a specific ordering from another thread " - what does it means - is it that reordering will be done by compiler that value of y meynot be updated even though y.store() is called?然后对于 std::memory_order_relaxed 意味着“没有线程可以指望来自另一个线程的特定排序”——这是什么意思——重新排序将由编译器完成,即使 y.store() 是,y 的值也不会被更新叫什么?
-Thread 1-
y.store (20, memory_order_relaxed)
x.store (10, memory_order_relaxed)
-Thread 2-
if (x.load (memory_order_relaxed) == 10)
{
assert (y.load(memory_order_relaxed) == 20) /* assert A */
y.store (10, memory_order_relaxed)
}
-Thread 3-
if (y.load (memory_order_relaxed) == 10)
assert (x.load(memory_order_relaxed) == 10) /* assert B */
For Acquire / release memory model is similar to the sequentially consistent mode, except it only applies a happens-before relationship to dependent variables. For Acquire / release memory model 类似于顺序一致模式,只是它只对因变量应用 happens-before 关系。
Assuming 'x' and 'y' are initially 0:
-Thread 1-
y.store (20, memory_order_release);
-Thread 2-
x.store (10, memory_order_release);
-Thread 3-
assert (y.load (memory_order_acquire) == 20 && x.load (memory_order_acquire) == 0)
-Thread 4-
assert (y.load (memory_order_acquire) == 0 && x.load (memory_order_acquire) == 10)
What does it means in explicit terms?用明确的术语来说是什么意思?
-Thread 1- -Thread 2-
y = 1 if (x.load() == 2)
x.store (2); assert (y == 1)
y = 1;
这并不意味着变量 y是原子变量,编译器只是保证y = 1;
happens before x.store (2);
发生在x.store (2);
. . If there was another thread 3 that manipulates variable y , assertion may fail due to the other thread.如果有另一个线程 3操作变量 y ,断言可能会由于另一个线程而失败。-Thread 1-
y.store (20, memory_order_relaxed) // 1-1
x.store (10, memory_order_relaxed) // 1-2
-Thread 2-
if (x.load (memory_order_relaxed) == 10) // 2-1
{
assert (y.load(memory_order_relaxed) == 20) /* assert A */
y.store (10, memory_order_relaxed) // 2-2
}
-Thread 3-
if (y.load (memory_order_relaxed) == 10) // 3-1
assert (x.load(memory_order_relaxed) == 10) /* assert B */
x
& y
does not have any dependency to each other.显然, x
& y
彼此没有任何依赖关系。 So compiler may change the order of execution for thread 1 , unlike std::memory_order_seq_cst , where y.store(20)
MUST executed before x.store(10)
happens.因此编译器可能会更改线程 1的执行顺序,这与std::memory_order_seq_cst不同,其中y.store(20)
必须在x.store(10)
发生之前执行。1-2
.简而言之,线程 3可能会看到最终更新的变量 y并获得 10,但不是1-2
的副作用。 Even tho thread 2 must have seen it's side-effect in order to store 10 into y, compiler does not guarantee instruction's side effect must have synchronized between threads( happens-before )即使线程 2必须看到它的副作用以便将 10 存储到 y 中,编译器也不保证指令的副作用必须在线程之间同步(发生之前)assert(y <= z)
is guaranteed to be passed. assert(y <= z)
保证通过。-Thread 1-
x.store (1, memory_order_relaxed)
x.store (2, memory_order_relaxed)
-Thread 2-
y = x.load (memory_order_relaxed)
z = x.load (memory_order_relaxed)
assert (y <= z)
2-2. 2-2。 is it that reordering will be done by compiler that value of y may not be updated even though y.store() is called?是否重新排序将由编译器完成,即使调用 y.store() 也可能不会更新 y 的值?
NO .不。 As I've described in 2., it means compiler may change the order of instructions that does not have data dependency.正如我在 2. 中所描述的,这意味着编译器可能会更改不具有数据依赖性的指令顺序。 Of course y must be updated when y.store()
is called.当然,在y.store()
时必须更新y 。 After all, that's the definition of atomic instruction.毕竟,这是原子指令的定义。
Assuming 'x' and 'y' are initially 0:
-Thread 1-
y.store (20, memory_order_release);
-Thread 2-
x.store (10, memory_order_release);
-Thread 3-
assert (y.load (memory_order_acquire) == 20 && x.load (memory_order_acquire) == 0)
-Thread 4-
assert (y.load (memory_order_acquire) == 0 && x.load (memory_order_acquire) == 10)
y.store()
must happens-before x.store()
or vice versa.所以在一致模式下, y.store()
必须发生在x.store()
之前,反之亦然。y.store()
happened before x.store()
.如果线程 3的断言通过,则意味着y.store()
发生在x.store()
之前。 So thread 4 must have seen y.load() == 20
before x.load() == 10
.所以线程 4必须在x.load() == 10
之前看到y.load() == 20
。 Therefore assert is failed.因此断言失败。 Same thing happens if thread 4 's assert gets passed.如果线程 4的断言通过,也会发生同样的事情。y.load()
→ thread 1 y.store()
→ thread 3 y.load()
→ thread 3 x.load()
→ thread 4 x.load()
线程 4 y.load()
→线程 1 y.store()
→线程 3 y.load()
→线程 3 x.load()
→线程 4 x.load()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.