Dispatch 1 — Compute Region Mask (unchanged)
One thread per command:
regionMask[i] : u32
Dispatch 2 — Block Histograms For ALL Regions
Each workgroup handles 256 commands.
Inside workgroup:
var localCounts[32] : u32;
Each thread:
mask = regionMask[i]
for r in 0..31:
if mask & (1 << r):
atomicAdd(localCounts[r], 1)
After barrier:
blockCounts[blockId][r] = localCounts[r]
Now you have:
blockCounts[256 blocks][32 regions]
Single dispatch.
Dispatch 3 — Scan Block Counts (Per Region)
Now scan across blocks:
For each region r independently:
blockOffsets[blockId][r]
This can be done in one dispatch:
32 workgroups
Each scans 256 values
Very small workload.
Also compute:
regionBase[r]
in same pass (scan total per region).
Still single dispatch.
Dispatch 4 — Final Stable Scatter
Each workgroup processes 256 commands again.
Inside workgroup:
We now need the true per-region local prefix.
We compute it properly using parallel scan (not atomics).
For region r:
Extract visibility bit
Do shared-memory exclusive scan
Compute:
dst =
regionBase[r]
- blockOffsets[blockId][r]
- localPrefix
Write to:
regionIndices[dst] = cmdIndex
This is still one dispatch.
Dispatch 1 — Compute Region Mask (unchanged)
One thread per command:
regionMask[i] : u32
Dispatch 2 — Block Histograms For ALL Regions
Each workgroup handles 256 commands.
Inside workgroup:
var localCounts[32] : u32;
Each thread:
mask = regionMask[i]
for r in 0..31:
if mask & (1 << r):
atomicAdd(localCounts[r], 1)
After barrier:
blockCounts[blockId][r] = localCounts[r]
Now you have:
blockCounts[256 blocks][32 regions]
Single dispatch.
Dispatch 3 — Scan Block Counts (Per Region)
Now scan across blocks:
For each region r independently:
blockOffsets[blockId][r]
This can be done in one dispatch:
32 workgroups
Each scans 256 values
Very small workload.
Also compute:
regionBase[r]
in same pass (scan total per region).
Still single dispatch.
Dispatch 4 — Final Stable Scatter
Each workgroup processes 256 commands again.
Inside workgroup:
We now need the true per-region local prefix.
We compute it properly using parallel scan (not atomics).
For region r:
Extract visibility bit
Do shared-memory exclusive scan
Compute:
dst =
regionBase[r]
Write to:
regionIndices[dst] = cmdIndex
This is still one dispatch.