Volatile Variables, CPU Caches & Memory Barriers (`Thread.MemoryBarrier`)
1Concept
Modern multi-core CPUs reorder memory instructions and cache variables in L1/L2 caches. The `volatile` keyword and `Thread.MemoryBarrier()` enforce hardware memory visibility across CPU cores.
2Architecture Diagram
Core 1 writes: flag = true (Cached in Core 1 L1 Cache)
│
▼ (Without Memory Barrier: Core 2 reads stale flag = false from its own L1 Cache!)
Thread.MemoryBarrier() ──> Flushes store buffers, forcing all CPU cores to synchronize RAM.3Code Example
C# 13 & .NET 9
using System;
using System.Threading;
public class MemoryBarrierDemo
{
private static volatile bool _running = true;
public static void Main()
{
var thread = new Thread(() =>
{
while (_running)
{
// volatile guarantees latest value is read from RAM
}
Console.WriteLine("Worker thread observed stop signal.");
});
thread.Start();
Thread.Sleep(10);
_running = false; // Writes to memory
thread.Join();
}
}4Expected Output
Worker thread observed stop signal.
5Key Takeaways
- ✓`volatile` prevents the C# JIT and CPU from caching variables in CPU registers.
- ✓`Volatile.Read` and `Volatile.Write` provide method-based memory fences.
- ✓Necessary for low-level ring buffers and lock-free data structures.