1

Why the following functions:

#include <atomic>

void store_release(std::atomic<int>& location, int val) {
    location.store(val, std::memory_order_release);
}

void store_seq_cst(std::atomic<int>& location, int val) {
   location.store(val, std::memory_order_seq_cst);
}

are compiled differently on x86-64 (godbolt):

store_release(std::atomic<int>&, int):
        mov     DWORD PTR [rdi], esi
        ret
store_seq_cst(std::atomic<int>&, int):
        xchg    esi, DWORD PTR [rdi]
        ret

even though the C++ standard states that store operation with std::memory_order_seq_cst order performs a release operation on affected memory location? Quote from 29.3 Order and consistency:

(1.2) memory_order_release,memory_order_acq_rel, and memory_order_seq_cst: a store operation performs a release operation on the affected memory location

  • What guarantees a xchg instruction has that mov does not have?
  • Why are these guarantees required for seq_cst order?
  • In which cases the visibility of store will be (practically) different for these 2 operations?
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
0xd34d10cc
  • 71
  • 2
  • 2
    `xchg` has an implicit `lock` prefix so it flushes the store buffer, just like `mov+mfence` which would also work but is usually slower. The visibility is unaffected; every store is eventually visible, but it affects *when* it will be visible wrt. later loads. – Peter Cordes Sep 03 '20 at 13:46

0 Answers0