The Uop Cache's Line Boundary Waste: Why Instructions That Straddle a 32-Byte Fetch Window Waste Half the Cache

2026-08-29

The Intel uop cache (DSB) is organized around a rigid rule that catches almost everyone by surprise: each entry corresponds to a single aligned 32-byte region of the original x86 instruction stream. Skylake-family cores can hold up to 6 uops per entry, up to 3 entries per 32-byte window, and — crucially — a single macro-instruction's uops cannot span two entries. If a x86 instruction crosses a 32-byte boundary, all of its uops get placed in the entry belonging to whichever 32-byte window starts the instruction. But the fetch of that instruction still counts against both windows' delivery bandwidth.

The waste compounds three ways:

Concrete example: Google's TCMalloc team hit this in 2019 when a compiler update reordered a hot allocation path. A frequently-taken branch instruction (6 bytes) landed at offset 28 within a 32-byte window — spilling 2 bytes into the next window. Nothing about the instructions themselves changed, but IPC on the hot path dropped ~8% because the loop no longer fit cleanly in DSB entries. The fix was a single-byte NOP inserted earlier in the function to shift alignment. Same instructions, same semantics, 8% faster.

Rule of thumb: A 32-byte window can hold at most ~18 uops across 3 entries, but only if instructions don't cross the boundary. Every boundary-crossing instruction costs you roughly one entry slot worth of delivery bandwidth — call it 6 uops of throughput opportunity. For a hot loop delivering 4 uops/cycle from the DSB, one boundary-crossing instruction per iteration can cost you an entire cycle.

This is why -falign-loops=32 exists in GCC, why LLVM's -mllvm -align-all-blocks=5 flag matters, and why performance engineers stare at objdump output looking for instructions at offsets 30 and 31. The compiler can't always fix it — sometimes a jump target must land where it lands. But awareness of the 32-byte grid is the difference between an 4.0 IPC loop and a 3.2 IPC one.

Key Takeaway: The uop cache indexes by aligned 32-byte fetch windows and refuses to split a single instruction across entries, so instructions crossing a 32-byte boundary silently fragment your DSB entries and throttle frontend delivery bandwidth.

All newsletters