Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to understand the changes to sequentially-consistent ordering in C++20?

P0668R5 made some changes to the sequentially-consistent ordering. The following example, from the proposal (also from cppreference), describes the motivation for the modification.

// Thread 1:
x.store(1, std::memory_order_seq_cst); // A
y.store(1, std::memory_order_release); // B
// Thread 2:
r1 = y.fetch_add(1, std::memory_order_seq_cst); // C
r2 = y.load(std::memory_order_relaxed); // D
// Thread 3:
y.store(3, std::memory_order_seq_cst); // E
r3 = x.load(std::memory_order_seq_cst); // F

where the initial values of x and y are 0.

According to the proposal, r1 is observed to be 1, r2 is 3, and r3 is 0. But this is not allowed by the pre-modified standard.

The indicated outcome here is disallowed by the current standard: All memory_order_seq_cst accesses must occur in a single total order, which is constrained to have F before A (since it doesn't observe the store), which must be before C (since it happens before it), which must be before E (since the fetch_add does not observe the store, which is forced to be last in modification order by the load in Thread 2). But this is disallowed since the standard requires the happens before ordering to be consistent with the sequential consistency ordering, and E, the last element of the sc order, happens before F, the first one.

To solve this problem, C++20 changed the meaning of strongly happens-before (the old meaning was renamed to simply happens-before). According to the modified rule, although A happens-before C, A does not strongly happens-before C, so A does not need to precede C in the single total order.

I'm wondering about the result of the modification. According to cppreference, the single total order of memory_order_seq_cst is C-E-F-A (I don't know why). But according to the happens-before rule, A still happens-before C, so the side effects of A should be visible to C. Does this mean that A precedes C in the modification order seen by thread 2? If so, does this mean that the single total order seen by all threads is not consistent? Can someone explain the above example in detail?

like image 426
Pluto Avatar asked Oct 16 '25 23:10

Pluto


1 Answers

Note A and C operate on different objects, so it's meaningless to say "the side effects of A should be visible to C". If you mean the side effect of B is visible to C, then yes, and it does not conflict with the single total modification order C-E-F-A:

a memory_order_seq_cst load gets its value either from the last memory_order_seq_cst modification, or from some non-memory_order_seq_cst modification that does not happen-before preceding memory_order_seq_cst modifications.

like image 193
xskxzr Avatar answered Oct 18 '25 13:10

xskxzr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!