Where §3.4.1 merged threads across warps, this family keeps each warp intact and improves how its own divergent paths are handled — on two axes: run the paths concurrently (multi-path parallelism), and rejoin them earlier (better convergence).
Multi-path parallelism
After a divergent branch, a warp’s threads form
| A | B | ∅ | B | C | ∅ | C | D | |
|---|---|---|---|---|---|---|---|---|
| t0 | ||||||||
| t1 | ||||||||
| t2 | ||||||||
| t3 |
time →
All four threads load data[i] and evaluate the branch: lanes 0–1 go to B, lanes 2–3 to C.
| A | B | C | B | C | D | |
|---|---|---|---|---|---|---|
| t0 | ||||||
| t1 | ||||||
| t2 | ||||||
| t3 |
time →
Same divergence: lanes 0–1 → B, lanes 2–3 → C. But now BOTH warp-splits sit in a warp-split table, both eligible to issue.
The proposals, in escalating generality:
- Dynamic Warp Subdivision (Meng et al.): a warp-split table beside the stack; splits run concurrently. DWS even splits at memory divergence (some threads hit L1, some miss) — the hitters run ahead, effectively prefetching for the missers.
- Dual-Path Execution (Rhu & Erez): cap it at two concurrent splits (the two at the TOS entry) — one extra PC + mask, a per-path scoreboard extension, and most of DWS’s benefit at a fraction of the complexity.
(MPM, ElTantawy et al.): drop the stack entirely for a warp-split table + reconvergence table. Any split may issue until its PC equals its RPC; arrivals accumulate in the reconvergence entry, which retires into a merged split when everyone’s in. A careful scoreboard extension tracks dependences per split without duplicating the whole scoreboard per thread. (Sound familiar? Volta’s convergence barriers are an industrial cousin.)Multi-Path execution multi-path executionLetting multiple warp-splits of one warp interleave (DWS, dual-path, MPM) to recover TLP during divergence.Glossary →
Better convergence
The immediate post-dominator is the earliest guaranteed reconvergence
point — but not always the earliest practical one. The classic case is a
loop with a rare break: the IPDOM sits after the loop, yet in the
common case threads meet again at the loop’s increment. (The book credits
this observation for NVIDIA’s break instruction.)
Step 1: Divergence at A — an LPC entry is born
Warp (threads 1,2,3,4) diverges at A's branch: thread 1 → B, threads 2–4 → C. The immediate post-dominator of A is F (the only guaranteed meeting point, because of the break). Three entries are pushed: a special LIKELY-convergence entry for E (empty mask, RPC=F), then the two path entries — each carrying LPC=E and LPos pointing at that special entry.
PC RPC LPC LPos Act.Thd.
F -- -- -- 1234
E F -- -- (empty) ← LPC entry
B F E 1 1
C F E 1 234 ← TOSOne tick = one stack state from Fig 3.19. Code: while(i<K){ X=data[i]; /*A*/ if(X==0) result[i]=Y; /*B, 25%*/ else if(X==1) break; /*C→D, rare 2%*/ i++; /*E*/ } return result[i]; /*F*/ — F is the immediate post-dominator, but 96% of threads could reconverge earlier, at E.
Two stack-free alternatives round out the axis:
(Diamos et al.): the compiler sorts basic blocks topologically so control only flows “downward”; each thread keeps its own PC in the register file; the hardware always executes the warp’s lowest-PC threads (the frontier), so everyone ahead implicitly waits. Especially strong for unstructured control flow (multi-expression conditionals, exceptions), and with no fixed budget of convergence points — where the LCP stack fields cap out.Thread frontiers thread frontiersPer-thread PCs + topologically sorted code; always run the lowest-PC threads so laggards catch up — no stack needed.Glossary →- Opportunistic Early Reconvergence (OREC, in MPM): at a divergent branch, if a warp-split with the same PC and RPC already exists in the table, create an early reconvergence entry and merge with it — capturing unstructured-control-flow reconvergence without any compiler help.
| DWS | Warp-split table; splits interleave; splits on memory divergence too | Splits fragment SIMD width until reconvergence |
| Dual-Path | Exactly two concurrent splits (the TOS pair) | Deeper splits wait their turn |
| Multi-Path (MPM) | Split + reconvergence tables replace the stack | Per-split dependence tracking (carefully, not per-thread duplication) |
| Likely convergence points | LPC/LPos stack fields catch early meeting points | Finite LPC slots per entry; needs analysis or profiles |
| Thread frontiers | Topologically sorted code + run-lowest-PC rule | Per-thread PCs in the register file; compiler support |
Check yourself
1. What does multi-path execution improve — and what does it NOT improve?
2. Dual-Path Execution (DPS) deliberately limits a warp to two concurrent splits. Why?
3. What two structures replace the SIMT stack in Multi-Path execution (MPM)?
4. In the likely-convergence walkthrough, why does reconverging at E (not F) help this loop?
5. How do thread frontiers guarantee reconvergence without a stack?