c++c++11memory-modelstdatomic

How do memory_order_seq_cst and memory_order_acq_rel differ?


Stores are release operations and loads are acquire operations for both. I know that memory_order_seq_cst is meant to impose an additional total ordering for all operations, but I'm failing to build an example where it isn't the case if all the memory_order_seq_cst are replaced by memory_order_acq_rel.

Do I miss something, or the difference is just a documentation effect, i.e. one should use memory_order_seq_cst if one intend not to play with a more relaxed model and use memory_order_acq_rel when constraining the relaxed model?


Solution

  • http://en.cppreference.com/w/cpp/atomic/memory_order has a good example at the bottom that only works with memory_order_seq_cst. Essentially memory_order_acq_rel provides read and write orderings relative to the atomic variable, while memory_order_seq_cst provides read and write ordering globally. That is, the sequentially consistent operations are visible in the same order across all threads.

    The example boils down to this:

    bool x= false;
    bool y= false;
    int z= 0;
    
    a() { x= true; }
    b() { y= true; }
    c() { while (!x); if (y) z++; }
    d() { while (!y); if (x) z++; }
    
    // kick off a, b, c, d, join all threads
    assert(z!=0);
    

    Operations on z are guarded by two atomic variables, not one, so you can't use acquire-release semantics to enforce that z is always incremented.