In this example, we have multiple threads incrementing a shared integer variable.
We expect that the final result is the number of threads times the number of increments per thread.
With std::atomic <uintNN_t>
, the result is correct.
With volatile uintNN_t
, the result is incorrect, even with Visual C++'s /volatile:ms
option for cl
.
References:
"[…]
Do not assume that volatile
has special meaning in the memory model. It does not. It is not – as
in some later languages – a synchronization mechanism. To get synchronization, use an atomic
(§41.3), a mutex (§42.3.1), or a condition_variable (§42.3.4).
[…]"
-
Generated x86_32 Assembler code to increment a 32-bit integer (in memory, pointed-to by
eax
) is:
— with volatile uint32_t
:
inc [dword ptr eax]
— with std::atomic <uint32_t>
:
mov ecx, 1
lock xadd [eax], ecx