Phase 20 of 30 · Topic 20.5

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.