Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the MOV x86 instruction implement a C++11 memory_order_release atomic store?

According to this https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html, a released store is implemented as MOV (into memory) on x86 (including x86-64).

According to his http://en.cppreference.com/w/cpp/atomic/memory_order

memory_order_release:

A store operation with this memory order performs the release operation: no memory accesses in the current thread can be reordered after this store. This ensures that all writes in the current thread are visible in other threads that acquire or the same atomic variable and writes that carry a dependency into the atomic variable become visible in other threads that consume the same atomic.

I understand that when memory_order_release is used, all memory stores done previously should finish before this one.

int a;
a = 10;
std::atomic<int> b;
b.store(50, std::memory_order_release); // i can be sure that 'a' is already 10, so processor can't reorder the stores to 'a' and 'b'

QUESTION: how is it possible that a bare MOV instruction (without an explicit memory fence) is sufficient for this behaviour? How does MOV tell the processor to finish all previous stores?

like image 443
Krab Avatar asked Apr 28 '15 14:04

Krab


1 Answers

There's memory reordering at run-time (done by CPU) and there's memory reordering at compile-time. Please read Jeff Preshing's article on compile-time reordering (and also great many other good ones on that blog) for further information.

memory_order_release prevents the compiler from reordering access to data, as well as emitting any necessary fencing or special instructions. In x86 asm, ordinary loads and stores already have acquire / release semantics, so blocking compile-time reordering is sufficient for acq_rel, but not seq_cst.

like image 133
rashmatash Avatar answered Nov 14 '22 04:11

rashmatash