2026-09-14
Out-of-order processors want loads to execute as early as possible, ideally before older stores whose addresses haven't been computed yet. The naive rule — "never let a load pass a store with an unknown address" — kills performance because most loads and stores don't overlap. The opposite extreme — "let every load fly past every store, and replay if you were wrong" — works fine when you're right, but the replay penalty (flush the pipe from the offending load) is 10–20 cycles. On code with any real store-to-load communication, this thrashes.
The insight: the same static load-store pair tends to alias repeatedly. If load A got in trouble because store B aliased last time, it will probably alias again. Just remember that. This is memory dependence prediction, and the elegant version is Chrysos and Emer's Store Sets (1998, shipped in the Alpha 21264).
How it works:
Concrete example: imagine a linked-list traversal while(p) { p->count++; p = p->next; }. The store p->count and the load p->next hit the same cache line but different addresses. On the first violation, the CPU builds a store set linking those two PCs. Every subsequent iteration, the load waits for the store's address to resolve — no more mis-speculation, no more 15-cycle flushes.
Rule of thumb: a 4K-entry SSIT with 5-bit SSIDs (32 store sets) catches >95% of memory-order violations on SPEC integer code. That's 2.5 KB of tables saving you thousands of pipeline flushes per million instructions — one of the highest-leverage predictors in the machine.
The subtle part is merging policy: if load L violates against store S1, and later against store S2, you can either add S2 to L's set or merge S1's whole set with S2's. Alpha did the latter; sets grow monotonically and are periodically flushed to keep them from swallowing the whole program.
