Shared-memory bank conflicts
Map words to banks, distinguish conflicts from broadcast, and validate padded or swizzled tensor tiles.
On this page
The question for today
What you’ll understand
- Compute bank indices for a stated 32-bit access model.
- Explain same-address read broadcast versus different-address bank conflicts.
- Evaluate padding while preserving global layout and synchronization.
Shared memory can reuse tensor data efficiently inside a block, but an awkward tile layout can serialize accesses to its banks. This lesson follows the CUDA 12.8.1 guide’s 32-bank, successive-32-bit-word mapping, using one warp’s scalar 32-bit accesses on an Ampere-class target. Do not extend the arithmetic unchanged to every wide instruction, swizzled layout, or transaction decomposition. First identify the access the hardware actually services.
Map word addresses, not source-array names
For the stated model, successive 32-bit words map to successive banks, wrapping after bank 31. Threads accessing distinct words in distinct banks can be serviced without a bank conflict for that request. Distinct addresses that map to the same bank can require multiple conflict-free operations. A row-major tile’s leading dimension therefore matters: reading a column can produce a very different bank pattern from reading its row, even though both use a two-dimensional array in source code.
Several lanes reading the same shared-memory location are a broadcast case, not a set of distinct-word bank conflicts. Do not diagnose it merely by counting how many lanes map to bank zero. Multiple writes to one location are also a correctness question; a convenient bank pattern does not make conflicting non-atomic writes a defined reduction. Distinguish the requested word addresses, the bank mapping, and the synchronization needed between producers and consumers before changing the layout.
Padding can change a column’s stride
A 32-by-32 row-major FP32 tile has a 32-word row stride. If lane ℓ reads row ℓ at one fixed column, all word indices have the same residue modulo 32 despite being different addresses. Padding the leading dimension to 33 words changes the residue progression so consecutive lanes reach consecutive banks. The extra column is storage overhead used to improve this access pattern; the logical tile can still contain only the original data elements.
Padding is not universally best. It consumes shared memory and may change occupancy, indexing, and copy behavior. Hopper’s TMA supports specific swizzle layouts, documented separately in CUDA 12.8.1, that also require correct producer and consumer indexing. A swizzle is not permission to reinterpret the same bytes with an incompatible row-major formula. Check both the global load pattern and the shared consumer pattern, because fixing one can worsen the other. Preserve numerical element identity through the transformation.
Measure the transaction and check its ordering
Inspect generated instructions and profiler bank-conflict metrics on the exact target before treating source-level stride arithmetic as a complete performance prediction. Different access widths and compiler transformations matter. Also test producer-consumer ordering: a conflict-free read before the corresponding write completes still reads invalid data. Appropriate warp or block synchronization depends on which threads communicate; do not add a block-wide barrier inside a branch reached by only some required participants. Correctness and layout optimization must be checked together.
The modular lab uses a deliberately smaller eight-residue analogy. Reset, set modulus to 8 and additive step to 4, predict the orbit period, then Step twice. Compare a fresh Reset with both modulus at 8 and additive step at 1, predicting before eight Steps. This shows how a stride changes visited residues. It is not the real 32-bank mapping, and it has no word addresses, broadcasts, memory instructions, or synchronization. Use the separate equation to analyze the actual tile.
Work it through
Pad a tile without changing its logical elements
A warp reads column zero of a row-major 32-by-32 FP32 shared tile, one row per lane. Compare leading dimensions 32 and 33 words. Assume the stated scalar 32-bank model and distinct row addresses.
With L = 32, lane ℓ reads word 32ℓ. Every residue is zero, so all 32 distinct words map to bank zero: a 32-way conflict in this model, not a same-address broadcast.
With L = 33, residues are 33ℓ mod 32 = ℓ. All 32 bank indices differ, eliminating this column-read conflict under the assumptions.
Storage grows from 32 × 32 × 4 = 4,096 bytes to 32 × 33 × 4 = 4,224 bytes, an extra 128 bytes. Check whether that allocation changes the real kernel’s residency.
One padding word per row changes this bank pattern while adding 128 bytes. It does not by itself validate copy alignment or synchronization.
The living notebook
Explore the model
Interactive lab · modular
Stride and residue coverage
Reset, set modulus m = 8 and additive step a = 4, predict the period, then Step twice. Compare a fresh Reset with both m = 8 and a = 1 before eight Steps. This eight-residue arithmetic analogy does not simulate 32 GPU banks or broadcast.
- Residue r0
- 0
- Orbit period · m/gcd(m,a)
- 12
- Distinct residues visited
- 1 of 12
Addition modulo m starts at zero: rₙ = na mod m. Playback advances two additions per second. The orbit has period m/gcd(m,a), including period one for a = 0. This is not a cryptographic security test or a primality algorithm. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forResidue coverage depends on stride, but real bank conflicts also depend on distinct addresses and instruction transactions.
Pause & reason
Check your understanding
Your turn
Try it yourself
For the same fixed-column scalar model, use leading dimension 34 and column zero. How many distinct banks do 32 lanes visit, and how many distinct addresses map to each visited bank?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
The bank increment is 34 mod 32 = 2; find its orbit length.
Compare with the solution
The even bank indices form an orbit of length 32/gcd(32,34) = 16. Across 32 lanes, each visited bank receives two distinct row addresses, yielding a two-way conflict under this simplified request model. This is not broadcast, and wider compiled accesses require their own transaction analysis.
Keep the idea
Take it with you
- Bank mapping depends on word stride and the instruction’s transaction shape.
- Identical-word read broadcast differs from distinct-word bank conflicts.
- Padding and swizzling must preserve indexing, resource budgets, and synchronization.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.