Memory access reordering rearranges, eliminates, or combines memory operations while preserving results allowed by the execution model. In multithreaded code, this invalidates assumptions that assignments execute exactly as written. section 7.2 section 7.1
Acquire operations prevent reads from moving earlier; release operations prevent writes from moving later. Memory barriers prevent reads and writes from crossing in either direction. Lock acquisition provides acquire semantics, while lock release provides release semantics. section 7.2
Use straightforward synchronization rules around shared data:
- Protect every access to shared data with the same lock. section 7.2
- Keep the lock object private so external code cannot interfere with the locking strategy. section 7.1
- Protect related fields together; assigning them in a careful order does not prevent inconsistent observations. section 7.1
Publishing a consistent pair
A setter that writes _x and _y inside lock(_lock), paired with a getter that reads both fields under the same lock, prevents another thread from observing a partial update. section 7.1
Set register to 0 (fast)
Store register to memory location "counter"(slow)
for(int i;i<100;++i)
{
Load from memory location "counter" into register (slow)
Increment value of register (fast)
Store register to memory location "counter"(slow)
}
The expanded operation sequence shows how repeated memory loads and stores may be transformed into register-local work, making source-level ordering an unsafe synchronization strategy. section 7.2
