Load-Store Queues and Memory Disambiguation: How Hardware Lets Loads Pass Stores Without Reading Stale Data

2026-06-13

Out-of-order CPUs want to execute loads as early as possible — a load that misses to DRAM costs 300 cycles, so waiting for older stores to resolve is catastrophic. But loads cannot blindly skip stores: if an older store writes address X and a younger load reads X, the load must see the store's value, not whatever was in cache. The load-store queue (LSQ) is the hardware that lets loads execute speculatively while guaranteeing correctness.

The LSQ is actually two structures working together: a store queue (SQ) holding in-flight stores with their addresses, data, and program order, and a load queue (LQ) holding in-flight loads with their addresses and the data they returned. Stores sit in the SQ until they retire — only then do they write to cache. Loads check the SQ on dispatch via a content-addressable memory (CAM) lookup on the address.

Three cases when a load executes:

That third case is where it gets spicy. When the older store's address finally resolves, hardware does a reverse CAM lookup against the LQ: did any younger load that already executed read this address? If yes — memory order violation. The pipeline flushes the load and everything after it, costing 15-20 cycles. This is called a memory disambiguation misprediction.

Real-world example: Intel's Nehalem (2008) added a memory disambiguation predictor that learns which loads historically conflict with prior stores. Aggressive loads execute early; risky ones stall. Intel claimed ~40% reduction in load latency on memcpy-style workloads where the compiler couldn't prove non-aliasing. AMD's Zen has a similar predictor with a small history table indexed by load PC.

Rule of thumb: SQ depth is roughly peak_store_throughput × retire_latency. A CPU retiring 1 store/cycle with 40-cycle ROB depth needs ~40 SQ entries. Skylake has 56 SQ / 72 LQ entries; Apple's M1 famously has ~150+ LQ entries, enabling its absurd memory-level parallelism. Each entry costs area (CAM cells are ~10× SRAM) and power, so depth is a deliberate trade against IPC gains.

Key Takeaway: The LSQ uses CAM-based address matching to forward store data to dependent loads and to detect when a speculatively-executed load read stale data, trading a rare flush penalty for the common-case freedom to reorder memory operations.

All newsletters