c++multithreadingc++11x86stdatomic

Memory Model in C++ : sequential consistency and atomicity


I have some questions connected with memory model in C++11.

On https://www.think-cell.com/assets/en/career/talks/pdf/think-cell_talk_memorymodel.pdf on the 29. slide is written

The C++ memory model guarantees sequential consistency

But, in my previous posts I learnt that C++ memory has weak memory model- the compiler can make reorder as he wants- he has to satisfy as if rule.


Solution

  • I think I figured out what that slide is talking about, from reading the earlier slides:

    slide 12: sequential consistency [Leslie Lamport, 1979]
    the result of any execution is the same as-if

    1. the operations of all threads are executed in some sequential order
    2. the operations of each thread appear in this sequence in the order specified by their program

    slide14: sequential consistency for data-race-free programs
    SC-DRF:

    • We take care our program does not contain data races
    • The system guarantees sequentially consistent execution

    So on slide 29, the authors are saying that once you avoid data-race UB using std::atomic, the program runs as-if everything happened in program order. (If all your std::atomic operations use the default memory_order_seq_cst).

    This is an interesting way to look at C++'s weak (for non-atomic objects) memory model. This looks like a good set of slides. SC atomic operations are strongly ordered, and are kind of like one-way barriers for non-atomic operations. (And for relaxed atomic operations if you have any).

    Note that being data-race-free means you can't look at non-atomic variables at arbitrary times, only when you've established that no other thread is writing them. (Usually via a synchronizes-with relationship with an acquire load seeing a release store done by the writer, or a mutex.) The data-race-free part is the key here; it's very easy to have data-race UB if you're not careful. When compiling to asm for real CPUs, this means non-atomic accesses can work as normal, while atomic<T> seq_cst accesses need to block compile-time and run-time reordering. https://preshing.com/20120625/memory-ordering-at-compile-time/


    Part two: Please don't make a habit of asking two very different questions at once.

    This "how does the CPU do it?" question would be a better fit as part of your later question: Atomicity on x86

    I have most of an answer to it already written, which I'll put there instead.