Everything in this chapter conspired to make the register file huge: zero-cost warp switching demands live registers for every thread of every warp (§3.1.3), so NVIDIA’s Fermi sustains 20,000+ in-flight threads with a 2 MB aggregate register file — larger than its last-level cache — built from low-port SRAM banks behind an operand collector. The bill: on a GTX280, the register file burns roughly 10% of total GPU power, split between access energy and leakage. Hence a research cottage industry:
3.6.1 Hierarchical register file
Gebhart et al.’s measurement: up to 70% of produced values are read
exactly once, only 10% more than twice. Short lifetimes beg for a small
fast tier — a
step 0An instruction produces value v1. Key statistic: up to 70% of produced values are read exactly ONCE, and only 10% more than twice — short lifetimes everywhere.
The load-bearing details: FIFO allocation for destinations only (source
misses aren’t cached — pollution), a compiler liveness bit marking each
value’s last read so dead values evict without writeback, and a
3.6.2–3.6.5 Four more attacks on the same structure
- Drowsy register file (Abdel-Majeed & Annavaram): tri-modal cells — ON / OFF (unallocated, no retention) / drowsy (retains state, low leakage, must wake before access). Policy: every allocated register goes drowsy immediately after each access — safe because fine-grained multithreading leaves long gaps between touches, and the deep pipeline swallows the wake-up latency.
(Tarjan & Skadron; Jeon et al.): while warps wait on memory, up to ~60% of registers hold dead values. Rename logical → physical registers on demand; reclaim at each register’s final read (annotated via compiler “metadata instructions” — and reclamation must respect branch divergence). Jeon et al.’s numbers: naive halving via spilling costs +73% runtime; renaming halves the RF with no loss, and renaming only high-numbered registers cuts the bookkeeping from 3.8 KB to ~1 KB — plus renaming enables power-gating whole subarrays.Register file virtualization register file virtualizationRenaming physical registers on demand (+ final-read metadata) to halve RF size or double threads without loss.Glossary →- Partitioned (Pilot) register file (Abdel-Majeed et al.): split into a small fast RF (regular SRAM, 4 entries/warp) and a large slow RF (near-threshold-voltage SRAM: far lower energy and leakage, multi-cycle access absorbed by the operand collector). A pilot CTA profiles each kernel’s hottest registers to decide placement; FinFET back-gate control drops inactive warps’ FRF into low power — two-level-scheduler benefits without the scheduler.
- RegLess (Kloosterman et al.): don’t cache the register file — eliminate it. Over ~100-cycle windows, kernels touch under 10% of a 2 MB RF; a compiler splits execution into intra-basic-block regions with bounded live sets, and a capacity manager preloads each region’s registers into a small 8-banked operand staging unit backed by global memory (L1-cached), compressing affine values (§3.5) in transit. Verilog-level evaluation: a 512-entry OSU slightly beats the 2 MB register file at 25% of the area and −11% total GPU energy.
| RFC + two-level scheduler | Cache short-lived values near the EU; liveness bits skip dead writebacks | Access energy |
| LRF/ORF (compile-time) | Compiler-orchestrated hierarchy, no tags | Access energy + hardware simplicity |
| Drowsy (tri-modal) RF | Every register drowsy right after each access | Leakage power |
| Virtualization (renaming) | Allocate physical regs on demand, reclaim at final read | Capacity (−50% size or 2× threads) |
| Pilot (FRF/SRF partition) | Hot registers in small fast SRAM, rest in NTV SRAM | Access energy + leakage |
| RegLess (staging unit) | Compiler regions + preloaded operand staging; no RF at all | Area (−75%) + energy (−11% GPU-wide) |
That closes the SIMT core. Chapter 4 descends into the other half of the machine — the memory system these thousands of threads are all shouting at.
Check yourself
1. Why is the GPU register file such a juicy research target?
2. Predict the RFC behavior (use the animation): a source operand misses the register file cache. What happens?
3. Why can a drowsy (tri-modal) register file put every register to sleep immediately after each access?
4. Jeon et al. compared two ways to halve the register file. What did they find?
5. RegLess replaces the register file with an operand staging unit. What makes that feasible?