Project 01
CUDA Histogram Optimization & Toolchain Analysis
31.42× median kernel speedup over a naive global-atomic baseline on NVIDIA GB10, measured on a 64 MiB high-contention workload with 8 active bins.
Compared global-atomic and block-private shared-memory histogram kernels on NVIDIA GB10. In a 50-sample-per-variant run built with nvcc V13.4.92, the shared implementation reduced median kernel time from 12.321952 ms to 0.392208 ms, a 31.42× speedup. Every recorded output bin was checked against a CPU reference.
C++
CUDA
Nsight Compute
Nsight Systems
GPU Benchmarking
PTX / SASS analysis
Primary results · Measured 30 Oct 2026
Single GPU · 64 MiB · 8 active bins · 50 samples/variant
DGX Spark / NVIDIA GB10 · Linux ARM64 · 48 SM · compute capability 12.1 · driver 580.178.04.
Input: 64 MiB unsigned bytes, 256 bins, only bins 0–7 active. Launch: 96 blocks × 256 threads.
nvcc 13.4.92 · new build
Primary result
31.42×
algorithm speedup
Naive median: 12.321952 ms
Shared median: 0.392208 ms
Shared P10–P90: 0.387894–0.396678 ms
Min–Max: 0.385440–0.402560 ms
nvcc 13.0.88 · adjacent control
Control run
10.63×
algorithm speedup
Naive median: 11.746224 ms
Shared median: 1.105152 ms
The preserved round2 binary was rerun for this control, not rebuilt.
Algorithm speedup = median(naive) / median(shared) within the same build. Naive uses one global atomicAdd per input element; shared uses a block-private shared-memory histogram followed by global atomic merging.
Toolchain investigation · a separate comparison
2.82×
Shared kernel: 1.105152 ms (13.0.88) → 0.392208 ms (13.4.92), 2.82× faster / 64.51% less time.
Rebuilding unchanged source with the 13.4 toolchain reduced the shared kernel’s median time from 1.105152 ms to 0.392208 ms compared with an adjacent 13.0-built control run on the same GB10. Exported PTX/SASS showed four-way loop unrolling and four independent byte loads scheduled before their dependent shared-atomic updates. The code-generation changes are consistent with improved load-level parallelism, but do not isolate a single compiler component or establish a unique performance cause.
The naive kernel was 4.90% slower in this comparison; the improvement should not be generalized to all kernels.
This build-to-build ratio is separate from the 31.42× algorithm speedup; the two use different baselines and should not be combined.
Static code evidence
The original kernel sources and benchmark harness remained byte-identical. nvcc, ptxas and nvlink version records all report V13.4.92. Build flags: -O3 -DNDEBUG -std=c++17 -arch=sm_121. The ordinary run used native sm_121 code with PTX JIT explicitly disabled; Linux long remained 64-bit.
The 13.0 shared loop processes one input per iteration. The 13.4 PTX is unrolled four ways; its final SASS places four independent LDG.E.U8 instructions before the first loaded-value consumer. The core shared-atomic/global-merge instruction kinds, two barriers and unconditional merge of all 256 bins remain unchanged.
These changes were generated by the toolchain, not a new handwritten kernel optimization. The build comparison also changes compiler components, headers and statically linked CUDART. Static instruction order supports a latency-hiding interpretation but does not prove actual overlap, isolate a compiler pass or establish a compiler bug.
Method
Per build and per implementation: one precheck, 20 warm-ups and 50 formal measurements. Each build recorded 100 formal samples across 142 calls and 36,352 per-bin checks against a CPU reference. Naive/shared execution alternated within each build.
CUDA-event kernel-only timing includes shared-kernel initialization, synchronization and final merging. It excludes H2D/D2H transfers, CPU validation, logging and output clearing outside the kernel. Quantiles use type 7 linear interpolation; no samples were discarded.
Limits & round3 profiling
This fixed eight-active-bin, high-contention input does not represent uniform 256-bin inputs or all histogram workloads. Each build has one ordinary measurement session, not 50 independent sessions. The fixed order was 13.4 then 13.0, without randomized or repeated crossover runs. Fixed clocks, per-sample telemetry and exclusive GPU use were not established. This is a single-GPU histogram microbenchmark, not an LLM training, inference, vLLM throughput or multi-GPU communication result.
Ordinary measurements and validation passed. Nsight Systems timeline capture succeeded; its individual kernel durations are separate from the ordinary-run statistics. Both Nsight Compute attempts failed during kernel preparation (exit code 9), so round3 has no valid new hardware counters.
Historical platform reference · Windows
Same workload definition · distinct measured configurations · not peak claims
NVIDIA GeForce RTX 5090 Laptop GPU
Windows x64
56.5×
historical median kernel speedup
Naive: 7.656368 ms → shared: 0.135440 ms
NVIDIA RTX Spark N1X
Windows ARM64 · nvcc V13.4.92
34.22×
historical median kernel speedup
Naive: 13.001120 ms → shared: 0.379968 ms
These historical values use the same workload definition but distinct measured configurations. The round3 GB10 shared median is approximately 3.22% higher than the historical N1X median; this is descriptive, not proof of equal platform performance.
Results are specific to this high-contention workload and the measured configurations; they are not general histogram or training speedup claims.
Historical profiling · Windows ARM64 / N1X / 13.4.92 session
Nsight Compute analysis on N1X showed substantially fewer global reduction requests at similar achieved occupancy. A separate Nsight Systems capture verified kernel and memory-transfer ordering. These observations come from that earlier session, are separate from round3, and do not establish counter behavior on GB10 or the Laptop GPU.
Single-GPU histogram · CUDA events · CPU-reference validation · Measured 30 Oct 2026 · Evidence reviewed 31 Oct 2026