Skip to content

[FEA]: Microbenchmarks for CUB cooperative primitives #12540

Open

Description

@gevtushenko

Is this a duplicate?

Area

CUB

Is your feature request related to a problem? Please describe.

Most CUB cooperative primitives have no microbenchmark, and the few that do are inconsistent. Without isolated latency and throughput numbers, we can't check a change to a block- or warp-level primitive for performance regressions, compare its algorithm variants, or decide which variant a device-level tuning policy should use. Device-level benchmarks exercise some of these primitives indirectly, but their results mix in global-memory traffic and tuning policies.

Current state under cub/benchmarks/bench/:

Primitive Benchmark Latency Throughput Algorithm sweep Items/s
BlockReduce reduce/block_reduce_sum.cu ✅ ✅ ✅ ❌
BlockScan scan/block_scan_sum.cu ❌ ✅ ❌ ❌
WarpReduce reduce/warp_reduce_{sum,min}.cu ❌ ✅ n/a (no logical-warp-size sweep) ❌
WarpScan scan/warp_scan_sum.cu ❌ ✅ n/a (no logical-warp-size sweep) ❌
detail::WarpBitonicSort bitonic_sort/warp_{keys,pairs}.cu ✅ ✅ n/a ✅

None of the following have a microbenchmark: BlockLoad, BlockStore, BlockExchange, BlockRadixSort, BlockMergeSort, BlockHistogram, BlockDiscontinuity, BlockAdjacentDifference, BlockShuffle, BlockRunLengthDecode, WarpLoad, WarpStore, WarpExchange, WarpMergeSort.

Describe the solution you'd like

Every public cooperative primitive should have a microbenchmark that follows one shared pattern. Block reduce benchmark https://github.com/NVIDIA/cccl/blob/main/cub/benchmarks/bench/reduce/block_reduce_sum.cu already follows most of it and can be used as a reference:

  • Mode axis (latency / throughput). Both modes use the same kernel, built on benchmark_kernel in nvbench_helper/device_side_benchmark.cuh, where each call's result feeds the next call so the calls form a dependency chain. latency launches a single block (or a single warp for warp primitives). throughput launches enough blocks to reach maximum occupancy on every SM.
  • Axes for the primitive's tuning knobs: the algorithm enum (e.g. BlockScanAlgorithm, BlockLoadAlgorithm, BlockHistogramAlgorithm), block size, items per thread, logical warp size, and value type. Compile-time parameters are dispatched from runtime axes with a switch, as in block_reduce_sum.cu.

This issue can be closed when all cooperative primitives have microbenchmarks covering all tuning knobs and modes (latency vs throughput).

Describe alternatives you've considered

No response

Additional context

No response

Activity

  1. fbusato commented on Nov 9, 2026

    @fbusato
    Contributor

    Without isolated latency and throughput numbers, we can't check a change to a block- or warp-level primitive for performance regressions, compare its algorithm variants, or decide which variant a device-level tuning policy should use.

    I don't fully agree with it. Microbenchmarking is great to compare variants if there is a large gap between their performance, otherwise device-level specific workload is the source of thrust. For this reason, I would not use microbenchmarking for tuning or regression checks.

    @gonidelis please add me to PR reviews as I worked on the original coverage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

  • Status
    Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions