WHAT: Occupancy is a ratio of active to maximum warps.
WHY: That is literally its definition — no resource limits to hunt for here, we are handed the active-warp count directly.
Occupancy=6448=0.75=75%Answer: 75%.
Recall Solution
Step 1 — warps per block. A warp is 32 threads, so 256/32=8 warps per block.
WHY divide by 32: the hardware always groups threads into fixed lanes of 32; that is the atom of scheduling.
Step 2 — total active warps.6 blocks×8 warps=48 warps.
Step 3 — occupancy.48/64=75%.
Answer: 8 warps/block, 75% occupancy.
Step 1 — registers per warp. Each warp has 32 threads, so it consumes 64×32=2048 registers.
WHY multiply by 32: every one of the 32 lanes needs its own private copy of each register; a warp's cost is the per-thread cost times 32.
Step 2 — how many such warps fit.Wregs=⌊204865,536⌋=32 warpsWHY the floor ⌊⌋: you cannot host a fractional warp — leftover registers that can't cover a full warp are simply wasted.
Step 3 — occupancy. With no other limit, min(32,64)=32.
Occupancy=6432=50%Answer: 32 warps, 50%.
Recall Solution
We must check each resource and take the minimum.
Register limit:Wregs=⌊32×3265,536⌋=⌊102465,536⌋=64 warpsShared-memory limit: how many 48 KB blocks fit in 164 KB?
⌊164/48⌋=3 blocks⇒3×8=24 warpsBlock-count limit:3 blocks is well under the 32-block max, so not binding.
Step — take the minimum:min(64,24,64)=24.
Occupancy=6424=37.5%Answer: shared memory is the bottleneck; 37.5%.
Recall Solution
WHY this tool:Little's Law answers exactly "how much must be in flight to keep a pipe full given a latency and a rate". That is precisely our question — we are not shrinking latency, we are overlapping it.
in flight=L×throughput=400×1=400 warp-instructionsAnswer: 400 (single-scheduler idealisation). The parent note explains why real SMs need only 16–32 warps: 4 schedulers plus instruction-level parallelism supply the concurrency SM-wide.
(a)Wregs=⌊65536/(128×32)⌋=⌊65536/4096⌋=16 warps ⇒16/64=25%.
(b)Wregs=⌊65536/(64×32)⌋=⌊65536/2048⌋=32 warps ⇒32/64=50%.
(c) WHY 128 can still win: if the kernel is memory-bound, 16 warps may already hide the load latency (recall 16–32 warps usually suffice SM-wide). Meanwhile keeping data in registers avoids spills to local memory that cost hundreds of cycles each. So 25% with no spills can beat 50% with spills.
Answer: (a) 25%; (b) 50%; (c) memory-bound kernels where the extra registers prevent spilling.
Recall Solution
WHY divide by loads-per-warp: each warp now contributes 2 outstanding requests, so it does the work of 2 toward filling the 400-cycle gap.
warps≳2400=200 (single-scheduler idealisation)WHY the real number is far lower: the A100 has 4 schedulers issuing from different warps in consecutive cycles, and the memory system services many requests in parallel (memory-level parallelism). Divide the idealised figure by the effective SM-wide issue width and you land in the empirical 16–32 warp range.
Answer: ≈200 idealised; in practice 16–32 warps due to 4 schedulers + MLP.
Recall Solution
WHAT limits each: A's ceiling is registers; B's ceiling is shared memory. The binding constraint is the only one worth relaxing (barrel plank logic).
Kernel A: cutting register use raises Wregs, directly lifting the minimum → occupancy rises.
Kernel B: more registers do nothing — shared memory is still the shortest plank; you'd raise a non-binding limit.
Answer: Kernel A benefits. For B you must cut shared-memory usage instead (e.g. smaller tiles).
Blocks: 5 blocks ≤32 max, so blocks give 5×4=20 warps (not extra-binding).
min(25,20,20,64)=20⇒20/64=31.25%.
Binding constraint: shared memory (20 warps).(b) Change: halve shared memory to 16 KB/block. Then ⌊164/16⌋=10 blocks ⇒10×4=40 warps for smem; registers still allow 25; block max allows min(10,32)×4=40. New minimum =min(25,40,40,64)=25.
Occupancy=25/64=39.06%WHY it stops at 25, not 40: once shared memory stops binding, registers become the new shortest plank at 25 warps. Synthesis lesson: fixing one bottleneck exposes the next.
Answer: (a) 31.25%, shared-memory bound. (b) 16 KB smem → ≈39.06%, now register bound.
Recall Solution
WHY roofline: it tells us the ceiling a kernel can reach from its intensity — compute-bound above the ridge, memory-bound below.
Step — ridge-point intensity (where the two ceilings meet):
AIridge=1555 GB/s19,500 GFLOP/s≈12.54 FLOP/byte
Our AI=0.5≪12.54, so we are far below the ridge → memory-bound.
(b) Implication: performance is set by feeding data, and moderate occupancy (∼50%, i.e. 16–32 warps) already hides load latency. Pushing to 100% gives diminishing returns; better to improve coalescing so each transaction moves useful bytes.
Answer: (a) memory-bound (0.5≪12.54); (b) ~50% occupancy suffices — chase coalescing, not occupancy.
S: ⌊65536/(48×32)⌋=⌊65536/1536⌋=42 warps ⇒42/64=65.6%.
(b) Which wins. Version S doubles occupancy — tempting. But it adds 2×400=800 cycles of serial spill latency on the critical path of every thread, whereas P saves 50 cycles by keeping data resident. Because the kernel is memory-bound, P's 21 warps (>16) already supply enough concurrency to hide the genuine load latency SM-wide. Extra warps in S hide nothing new but pay the spill tax.
Decision: Version P is faster. Occupancy rose in S, yet per-thread critical-path latency exploded — and once latency is already hidden, more warps don't help.
Answer: (a) P ≈32.8%, S ≈65.6%; (b) P wins — spills add 800 serial cycles that no amount of occupancy recovers here.
Recall Solution
Warp scheduling view: a scheduler picks a ready warp each cycle. A stalled warp (waiting on its load) is not ready, so if it is the only warp, the scheduler has nothing to issue → the SM idles.
SM architecture view: context (registers) for many warps lives on-chip simultaneously, making a switch free — but only if other warps exist to switch to. One warp = nothing to switch to.
Little's Law view: in-flight requests needed =L×rate. A lone warp issues one load then must wait; it cannot keep 400 cycles' worth of independent requests outstanding by itself, because its later instructions depend on that load's result.
Rule of thumb: you need multiple independent warps — empirically 16–32 on modern SMs — to keep the 4 schedulers fed and the memory system busy while any one warp waits.
Answer: latency hiding is inherently a between-warps mechanism; ILP within one warp is bounded by dependencies, so ≥16–32 warps is the practical minimum.
Recall Quick self-test (cloze)
Occupancy = active warps divided by maximum warps per SM.
The occupancy formula takes the minimum of all resource limits.
Registers are billed per warp as per-thread count times 32.
A single warp cannot hide its own load latency because latency hiding is a between-warps mechanism.
What is the ridge-point intensity on the A100 (19.5 TFLOP/s, 1555 GB/s)?
About 12.54 FLOP/byte
Why floor the warp counts?
You cannot host a fractional warp; leftover resource is wasted
For a memory-bound kernel below the roofline ridge, is 100% occupancy worth chasing?
No — ~50% already hides latency; fix coalescing instead