Repository navigation
Parallel for cuda counts - #46
Merged
Merged
Conversation
itr_index recomputed ceiling_div(end - begin, step) per dimension in every thread. Compute the counts once with itr_counts and pass them through parallel_for_function and reduction_contribution instead. L2-resident copy vs hand-written kernel: 2D 1.80x -> 1.42x, 3D 3.10x -> 2.23x. 3D DRAM-bound: 1.38x -> 1.00x.
…::Bulk cub's for_each agent stores a copy of the functor, so a functor indexed with a runtime value was copied into every thread's local memory (2 KB functor: 118x slower than a raw kernel, 8 KB: 449x). The new kernel takes the operation as a const kernel parameter and calls a const operator(), so nothing is copied. Also drops per-call host cost from +0.33 us to +0.08 us over a raw launch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Faster CUDA
parallel_for: host-computed counts and an xpu kernelSummary
Two changes to the CUDA path of
parallel_for(and the CUDAparallel_reduce_sumindex math):itr_indexused to recomputeceiling_div(end - begin, step)per dimension in every thread. The newitr_countscomputes them once per launch and passes them throughparallel_for_functionandreduction_contribution. This removes one 64-bit divide per dimension per element, along with the device-sideprintf/trap fromceiling_div's zero check.cub::DeviceFor::Bulk. CUB'sfor_eachagent stores a copy of the functor (agent_t{tile_base, op}). When the functor is indexed with a runtime value, every thread copies the whole functor into local memory. The newparallel_for_kerneltakes the operation as aconstkernel parameter and calls aconstoperator(), so nothing is copied.Results (RTX 4060 Laptop, ratio = xpu time / hand-written raw CUDA, 1.00 = no overhead)
Range counts,
parallel_forcopy:Per-element divides: 1.5 → 1.0 (2D), 3 → 2 (3D).
xpu kernel, functor carrying a lookup table (GPU kernel time, Nsight Systems medians):
Host cost per launch over a raw
<<<>>>: +0.33 µs → +0.08 µs.Testing
ctest: 11/11 on the CUDA and CPU builds, after rebasing ontomain(parallel_reduce_sum: drop caller scratch, keep default pool cached #10).begin0/1/4,step1/2/3/5 with uneven extents). Every expected index was visited exactly once, and nothing outside the range was visited.Known limitations / follow-ups
linear / countdivide per dimension.cuda::fast_mod_divon host-precomputed divisors, plus a 32-bit index path whentotal <= INT32_MAX, should remove most of it.parallel_forstill has no stream parameter. It always launches on the legacy default stream, so it waits on other streams' work and is not captured by CUDA Graphs that record on a user stream.