4 ms·
The C/C++ memory model starts with Java's data-race free memory model, but makes data races fully UB. Atomics are introduced into C/C++ that allows fine-grained
by jcranmer 15d ago
The C/C++ memory model starts with Java's data-race free memory model, but makes data races fully UB. Atomics are introduced into C/C++ that allows fine-grained definition of synchronization, with four different models of atomics: sequentially-consistent (equivalent to Java's volatile), release-acquire, release-consume, and relaxed (which are not synchronizing and are therefore closer to a defined data race than proper atomics). The Java 5 memory model doesn't have the concept of atomics, except that volatile variables act like C/C++ sequentially-consistent atomics.
Relaxed atomics took a couple of tries to specify, and still have a known out-of-thin-air hole that people are still struggling to solve. But the problem with relaxed atomics is that the practical operational semantics are pretty clear, but the formal model is quite tricky for various reasons.
Sequentially-consistent matches the model that most people naively think is going on in hardware (execute a single instruction at a time from a random thread). Release-acquire is a slight relaxation of that model that works well most of the time; the main difference between sequentially-consistent and release-acquire is that release-acquire requires you to specifically release and acquire on the same memory location to get the synchronization, whereas sequentially-consistent synchronizes across different memory locations. Since most multithreaded code tends to have a concept of something like a lock or mutex that is guarding access to a particular region of memory, release-acquire is usually sufficient.
Release-consume is supposed to be release-acquire, but only for data-dependent loads of the consume. This is the only part of the memory model that has really failed, and that's because compilers cannot really guarantee preservation of data dependence in the optimizer. (This also comes up with pointer provenance, FWIW).