2026-09-06
You already know Intel's uop cache (DSB) organizes decoded µops into 32-byte fetch windows, and that each window holds up to 3 "ways" of 6 µops each — 18 µops max per aligned 32-byte chunk of x86 code. What's less obvious: the DSB isn't just alignment-sensitive on the loop's start address. It's sensitive to every branch target inside the loop, because each taken branch forces a new DSB line to begin at that target's 32-byte window.
Here's the mechanic. When the frontend switches to DSB delivery, it fetches from the set indexed by the current IP's 32-byte-aligned base. If control enters that window at offset 20 (say, a jump target 20 bytes into the window), the DSB can only deliver µops that were built starting from that offset. Any µops sitting in the same window before offset 20 are unreachable from this entry point. Worse: those pre-offset µops still consume ways in the set. A window entered at three different offsets by three different branches needs three separate way entries — and you only get three ways per set.
Concrete example. A hot loop of 40 x86 bytes. If it starts at address 0x1000 (32-byte aligned), it spans windows 0x1000 and 0x1020, and the entry is at offset 0 — one way per window, fits fine. Now the linker shifts the loop to 0x100C. It now spans 0x1000, 0x1020, and 0x1040. The entry into window 0x1000 is at offset 12, meaning bytes 0–11 of that window (belonging to whatever function came before) share the same set. If that neighbor is also hot and entered at offset 0, you've just created a way conflict: two different entry points into the same 32-byte window compete for the 3 ways. Eviction begins. DSB hit rate collapses. The loop falls back to the legacy decoders — 4 µops/cycle instead of 6.
Rule of thumb: aligning a hot loop's start to 32 bytes is table stakes. But if the loop contains internal branch targets (unrolled body labels, jump-into-middle patterns, computed gotos), each target's 32-byte window also needs to be "cleanly entered" — ideally at offset 0, or at least at an offset that doesn't collide with other hot code in the same set. Compilers use .p2align 5 on internal labels for exactly this reason.
Detection: watch IDQ.DSB_UOPS vs IDQ.MITE_UOPS — a sudden shift toward MITE after a small code change usually means a DSB way conflict, not a capacity miss.
