SIMT divergence: count active lanes without assuming lockstep
Analyze branch paths within a warp and use explicit synchronization under Volta-style independent thread scheduling.
On this page
The question for today
What you’ll understand
- Compute a masked-path useful-lane fraction under an explicit cost model.
- Distinguish divergence from a race or an invalid barrier.
- Explain why independent scheduling requires explicit warp cooperation.
A warp can contain threads that choose different control-flow paths. The implementation executes the required paths with appropriate participating lanes, which can leave issue capacity serving only part of the warp. This is divergence, but it is not automatically a correctness error. Correctness fails when the program also assumes undocumented lockstep behavior, reads data without synchronization, or calls a collective with inconsistent participation. We focus on NVIDIA’s documented Volta introduction of independent thread scheduling and CUDA12.6 synchronization rules.
A branch partitions work inside a warp
Imagine eight lanes taking a short branch and 24 taking a longer one. In a simple serialized masked-path model, both nonempty paths execute, each with its own active subset. The inactive lanes do not contribute useful lane work on that path. If all lanes take the same branch, the other path need not execute under this model. Divergence depends on how data is grouped into warps, not merely on the whole dataset having equal counts of two outcomes.
A compiler may predicate small regions or transform control flow, and hardware scheduling is more involved than the toy accounting. Do not label every conditional a measured slowdown or infer an exact penalty from source code alone. Grouping similar work can reduce long divergent regions, but preprocessing, reordered memory access, and load imbalance can offset the benefit. First preserve semantics, inspect generated behavior where useful, and measure the actual kernel with representative input distributions.
Independent scheduling is not independent correctness
Starting with Volta, independent thread scheduling maintains finer-grained execution state, so old code that relied on implicit warp lockstep can be wrong. A shared-memory write by one lane is not automatically safe to read by another because both belong to the same warp. Use the documented synchronization primitive and participation mask for the actual communicating group. The relevant *_sync intrinsics define participation requirements, but not all of them imply a memory barrier; a warp shuffle and a shared-memory handoff have different contracts.
A block barrier must be reached as required by all non-exited block threads, and a warp collective must use a valid matching participating set. A mask captured inside one branch is not automatically proof of the full intended logical group. Reconvergence of control flow should not be treated as a universal memory-ordering primitive. Compute Sanitizer’s synccheck and racecheck can help find some violations, but their scopes differ and a clean run does not prove every possible schedule is race-free.
Use a distribution only when its assumptions fit
A branch outcome can correlate strongly with neighboring data, so independent Bernoulli outcomes are not a default property of a warp. A dataset sorted by category can produce mostly uniform warps even if half the total data belongs to each category. Conversely, alternating categories can split many warps. Build adversarial data layouts in tests, including partial final warps, and separate control-flow efficiency from memory coalescing. A layout change can improve one while worsening the other.
The sampling lab permits a deliberately hypothetical branch-label model. Reset, set success probability p=0.5 and sample size n=32, predict mean fraction 0.5 and variance 0.25/32, then Step. The bars are the exact binomial distribution, and playback highlights outcomes rather than executing random branches. It is not a warp scheduler or a divergence-timing simulator. Its independence assumption lets you reason about possible branch counts, while the actual instruction-path cost still needs a separate execution model.
Work it through
Two masked paths with unequal costs
One full warp has eight lanes on path A and 24 on path B. Assume serialized nonempty paths with six and ten equal-cost instruction positions, respectively; ignore all other costs.
Path A contributes 8×6=48 useful lane-instruction positions, while path B contributes 24×10=240. Total useful work in this accounting is 288 lane-instruction positions.
The two paths occupy 6+10=16 issued positions across 32 lane slots, giving 512 available lane-position slots under the declared model.
The useful fraction is 288/512=0.5625, or 56.25 percent. This is not a predicted speedup relative to an arbitrary reorganized kernel; instruction mix, scheduling, memory traffic, and regrouping cost are outside the model.
The fraction exposes masked work under explicit assumptions. Divergence can reduce utilization without making the branch logically incorrect.
The living notebook
Explore the model
Interactive lab · sampling
Hypothetical independent lane labels
Reset, set p=0.5 and n=32, predict mean proportion 0.5 and variance 0.0078125, then Step. Exact binomial bars describe independent labels; playback highlights outcomes. This is not random execution, a warp scheduler, or a divergence benchmark.
- Mean sample proportion
- 0.5
- Sample-mean variance
- 0.0125
- Uniform CDF error bound
- ≤ 0.1062
Exact binomial masses for the mean of n independent Bernoulli trials, compared with normal mass between adjacent half-count boundaries; normal tails outside the finite support remain outside the bars. Playback highlights outcomes, not random samples. The Berry–Esseen bound applies to standardized CDFs, not individual bars or continuity-corrected errors. At p = 0 or 1, normal comparison and that bound are disabled. Normal-CDF evaluation uses a numerical approximation with absolute error below 7.5×10⁻⁸ (at most 1.5×10⁻⁷ per interval, before rounding). 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 forA count distribution and an instruction execution cost are separate models with separate assumptions.
Pause & reason
Check your understanding
Your turn
Try it yourself
Under the same masked-path model, 16 lanes take a four-position path and 16 take an eight-position path. Compute useful fraction. Does that calculation prove a data race?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Count useful lane positions and total lane slots, then distinguish efficiency from ordering correctness.
Compare with the solution
Useful work is 16×4+16×8=192, and available slots are 32×12=384, so the fraction is 50 percent. This efficiency calculation neither proves nor disproves a race; shared-memory accesses and synchronization must be examined separately.
Keep the idea
Take it with you
- Divergence is a control-flow utilization issue with workload-dependent cost.
- Volta-style scheduling requires explicit valid warp cooperation.
- Participation masks and memory-ordering guarantees must be checked per primitive.
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.