2026-06-27
When your CPU emits a physical address to the memory controller, that 40-something-bit number doesn't go straight to DRAM. The controller chops it into pieces and uses each piece to pick a channel, rank, bank group, bank, row, and column. The mapping function — which bits go where — is one of the most impactful and least-discussed knobs in modern systems.
The fundamental tension: you want sequential accesses to hit the same row (row-buffer hits are ~10x faster), but you want parallel accesses to hit different banks and channels (so they overlap instead of serializing).
The standard trick is to put the column bits at the bottom (so a single cache line lives in one row), then bank and channel bits next (so the very next cache line goes to a different bank/channel), and finally row bits at the top. This is called a page-interleaved mapping with bank XOR hashing.
The XOR hashing matters enormously. A naive mapping like row | bank | column means a stride-equal-to-bank-size access pattern (common with power-of-two array sizes) hits the same bank every time — destroying bank-level parallelism. So controllers XOR several high-order address bits into the bank index, scattering pathological strides across all banks.
Concrete example: A DDR4 system with 2 channels, 8 banks per rank, 1KB row buffer, 64B cache lines. Bits [5:0] are byte offset. Bits [6] selects channel. Bits [9:7] select column within the row (sort of — interleaved with bank). Bits [12:10] select bank, XORed with bits [22:20] of the row. Bits [13+] are the row. Walking an array sequentially: every cache line alternates channels, and every 8 cache lines rotates through all banks before reusing the row buffer.
Rule of thumb: if your working set stride is a large power of two (say, 4KB — one OS page), you're likely hammering one bank repeatedly. Add a small offset (push your array to a 4160-byte stride instead of 4096) and watch bandwidth jump 2-4x. This is the DRAM version of cache associativity conflicts.
AMD publishes its DRAM Address Map registers (DRAM_HASH); Intel keeps theirs secret, but researchers have reverse-engineered them (it's how Rowhammer attackers find same-bank addresses). Cloud providers care deeply: a noisy neighbor that happens to map to your banks can tank your memory latency without ever touching your cache.
The mapping is set at boot by BIOS/firmware based on DIMM topology, and is usually invisible to the OS — but it silently shapes every memory-bound workload you run.
