I see. Thank you. 

I presume your answer is intended to state the same thing as Martin's answer. 
However, I'm a bit perplexed by 
the code snippet you supplied. Both variables are declared '_Atomic' in your 
code. Which means that the 
compiler (GCC x86-64 at least) will generate an 'xchg' (with an implied 'lock') 
in response to a simple 
assignment. This is what originally prompted my question. With locked 'xchg' 
the memory ordering issue you 
describe cannot occur, can it? Only if we remove the '_Atomic' qualifiers from 
your declarations, the compiler 
will resort to using 'mov' to implement simple assignment, which has weaker 
ordering semantics 
('memory_order_seq_cst', i.e. just 'release' in this particular case), and 
which can lead to 
different observers seeing different orders of 'x' and 'y' modifications.

Is my above interpretation of your answer correct? Or am I still missing 
something?

> On 09/25/2026 12:20 AM PDT LIU Hao <[email protected]> wrote:
> 
>  
> 在 2026-9-25 12:12, Andrey Tarasevich via Gcc 写道:
> > My question is: is there a tangible rationale/reason for the difference? I 
> > do understand that "memory-immediate operand" version of `mov` instruction 
> > is not atomic as a whole. But if I'm not mistaken, the store operation 
> > performed by such a `mov` is still perfectly atomic by itself (provided the 
> > memory location is aligned correctly). Which means that for the above 
> > purposes a plain `mov` would still satisfy the requirements of atomic 
> > behavior. Nevertheless, the code generator opts for a separate load into 
> > `eax` followed by an atomic `xchg`. Why? Is there a reason to prefer that 
> > latter approach? Am I missing something about the `mov` version?
> It's because the builtin assignment operator writes an `_Atomic` object with 
> `memory_order_seq_cst`. Given
> 
>     // aligned to avoid false sharing
>     _Alignas(64) _Atomic int x = 0;
>     _Alignas(64) _Atomic int y = 0;
> 
>     void
>     thread_X(void)
>       {
>         // same as `atomic_store_explicit(&x, 1, memory_order_seq_cst)`
>         x = 1;
>       }
> 
>     void
>     thread_Y(void)
>       {
>         // same as `atomic_store_explicit(&y, 1, memory_order_seq_cst)`
>         y = 1;
>       }
> 
> 
> The order of the two stores are indeterminate, but all the other threads must 
> see the same; it is not 
> allowed that thread foo sees `x == 1` and `y == 0` (not updated yet) but 
> thread bar sees `x == 0` and `y 
> == 1`.
> 
> And that's why these stores are implemented with XCHG.
> 
> 
> -- 
> Best regards,
> LIU Hao

Reply via email to