std::atomic | compare_exchange_weak vs. compare_exchange_strong

The note gives a clue, referring to LL/SC architectures. From the Wikipedia article:

If any updates have occurred, the store-conditional is guaranteed to fail, even if the value read by the load-link has since been restored. As such, an LL/SC pair is stronger than a read followed by a compare-and-swap (CAS), which will not detect updates if the old value has been restored (see ABA problem).

Real implementations of LL/SC do not always succeed if there are no concurrent updates to the memory location in question. Any exceptional events between the two operations, such as a context switch, another load-link, or even (on many platforms) another load or store operation, will cause the store-conditional to spuriously fail.

On LL/SC chips the compare_exchange will be implemented in terms of LL/SC, which can spuriously fail, so compare_exchange_strong needs extra overhead to retry in the case of failure. Providing both compare_exchange_strong and compare_exchange_weak allows the programmer to decide whether they want the library to handle spurious failures (in which case they'd use compare_exchange_strong) or if they want to handle it in their own code (in which case they'd use compare_exchange_weak)


It has to do with the shared memory consistency model that the hardware implements. For those hardware architectures that implement some kind of relaxed consistency model (e.g. release semantics), the strong operations you refer to above can have a high overhead, and thus experts can use the weaker forms to implement algorithms that perform well also on those relaxed consistency architectures.

For more info, see e.g.

http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-95-7.pdf

Chapter 12 and Appendix C in http://kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html