Skip to content

Spread each segment of the segmented bitmask reduction across several blocks - #23686

Draft
vuule wants to merge 2 commits into
NVIDIA:mainfrom
vuule:segmented-bitmask-binop-parallelism
Draft

Spread each segment of the segmented bitmask reduction across several blocks#23686
vuule wants to merge 2 commits into
NVIDIA:mainfrom
vuule:segmented-bitmask-binop-parallelism

Conversation

@vuule

@vuule vuule commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Description

segmented_offset_bitmask_binop assigned one warp to each segment, so a segment's entire null mask was walked by 32 threads regardless of how long it is. For the struct null mask reduction this kernel exists to serve, a segment is one column's mask and its length is the table's row count, so reducing 192 masks of 500k rows ran on 6144 threads and reached roughly a tenth of achievable bandwidth. Blocks now cooperate on a segment when there are few segments, with each segment's null count accumulated across its blocks.

The existing parquet_read_fixed_width_struct is 5.2% to 6.2% faster end to end on an A100 80GB, a flat ~0.62 ms in all four configurations: the Parquet reader calls enforce_null_consistency on every struct hierarchy it produces, and that is this kernel. The existing parquet_read_decode -a data_type=STRUCT shows the same ~0.3 ms absolute saving, worth 1.4% to 2.4% there since string decode dominates that profile.

In isolation, segmented_bitmask_and on 8 to 512 segments of 100k to 1M bits is 23% to 98% faster. The existing bitmask axes stop at 128-bit masks, which fit in a handful of words and cannot show this, so a case with mask sizes in the range of real table row counts is added; those existing narrow configurations are unchanged within noise.

Independent of #23484, which removes the mask allocations on the same path. The two compose: 23484 calls inplace_segmented_bitmask_binop directly instead of segmented_bitmask_and, which is the same entry point reparallelized here and dispatches to the same kernel.

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

…blocks

The kernel gave each segment a single warp, so the whole null mask of a
column was walked by 32 threads: reducing 192 masks of 500k rows was only
6144 threads for 3M words and ran at roughly a tenth of achievable
bandwidth. Blocks now cooperate on a segment when there are few of them,
with the per-segment null count accumulated across the blocks.

The existing benchmark axes only cover masks of up to 128 bits, which fit
in a handful of words and cannot show this, so add a case with mask sizes
in the range of real table row counts.
@copy-pr-bot

copy-pr-bot Bot commented Aug 17, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the libcudf Affects libcudf (C++/CUDA) code. label Aug 17, 2026
@vuule vuule added Performance Performance related issue improvement Improvement / enhancement to an existing function non-breaking Non-breaking change labels Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improvement / enhancement to an existing function libcudf Affects libcudf (C++/CUDA) code. non-breaking Non-breaking change Performance Performance related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant