Atomic Memory Ordering Models
Written
- Source: Atomics - The Rustonomicon, Relaxed-Memory Concurrency Synchronization Patterns | From Pencil to Metal
- This mostly focuses on Rust's model, which is in turn derived from the C++20 model. Most of the time you'll just want to use a normal Mutex or something, which already uses a lot of these types of operations under the hood, but these can be useful for more advanced algorithms.
Acquire
andRelease
- Acquire mode ensures that all writes after the Acquire will only be visible after the Acquire operation is visible.
- Release mode ensures that all writes before the Release will be visible before the Release operation is visible.
- These modes are usually paired, with one thread doing an Acquire, running some code, and then doing a Release.
- It is also feasible for the first thread to only do a Release, if it only needs to notify when it's done writing and does not have to indicate that a write is in progress.
- This is useful for lock-free algorithms, where you want to ensure that the data is visible to the other thread when you perform the Release.
- Generally the reader, in another thread, will then Acquire the same memory location before doing its reads, to ensure that it sees all the writes.
AcqRel
- This is a combination of
Acquire
andRelease
. When doing an atomic operation inAcqRel
mode, any other thread that does anAcquire
orAcqRel
atomic load from that location will be guaranteed to see all writes to other locations that took place before the first thread's atomic write. - This is most useful when your thread needs to both read data written by another thread, and write its own data.
- This is a combination of
SeqCst
- This mode is similar to
AcqRel
, but also ensures that all threads will see allSeqCst
operations in the same order. This is rarely necessary. (See SeqCst as a default atomic ordering considered harmful · Issue #166 · rust-lang/nomicon for a good explanation.)
- This mode is similar to
- Relaxed
- Relaxed operations provide no guarantees about ordering of other memory accesses.
- This means that you can use it for atomic read-modify-write operations on a single memory location, but not to synchronize accesses to other data.