Repository navigation
Conversation
When the fill arguments are variants, index_visitor runs through variant2::visit and is not inlined. The loop then reads its bounds and stride through `this` on every iteration and the vectorizer gives up. Copy the bounds to locals and give the first axis a compile-time stride. Measured with a 1D regular axis and 1M doubles (clang, Apple M5 Pro): variant argument 3.3 -> 0.8 ns/element, same as a plain span. Assisted-by: ClaudeCode:claude-fable-5-1 ClaudeCode:claude-fable-5-1
This was referenced Nov 2, 2026
henryiii
added a commit
to henryiii/boost-histogram
that referenced
this pull request
Nov 2, 2026
GCC defaults to -ftrapping-math, which blocks if-conversion of the regular axis index computation, so the fill loop stays scalar and branchy. Nothing in the extension relies on floating-point exceptions. Linux (gcc 14, docker), 1D Regular axis, 1M doubles: 3.95 -> 0.98 ns/element together with boostorg/histogram#451. Assisted-by: ClaudeCode:claude-fable-5-1
henryiii
marked this pull request as ready for review
November 3, 2026 00:20
This branch has not been deployed
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.
This trick allow the inner loop of a variant fill to be vectorized on Clang. On GCC, you have to pass
--no-trapping-mathto get it to optimize, doesn't seem to be a way around that. This provides a nice speedup on variants, better matching non-variant fills in performance.For some reason, Claude didn't capture the full table below when making the PR from my session, so pasting it in here (includes the flag on GCC):
Results, 1D Regular(100), 1M doubles, ns/element
The GCC speedup for boost-histogram (Python) requires scikit-hep/boost-histogram#1203 too.
🤖 AI text below 🤖
When
fillreceives variant arguments (as boost-histogram always does from Python),index_visitorruns throughvariant2::visitand is not inlined. The loop then readsbegin_,size_andstride_throughthison every iteration, so clang treats it as uncountable and does not vectorize it. This PR copies the bounds to locals and splits the loop onstride_ == 1, which gives the first axis a compile-time stride.Measured with a 1D
regular<>axis,dense_storage<int64_t>and 1M normally distributed doubles (clang 17, Apple M5 Pro, ns/element):span<const double>variant<double, span<const double>>End to end in boost-histogram,
h.fill(x)on a 1DRegularaxis goes from 3.3 to 0.9 ns/element, and 2D fills also get faster.gcc is not helped by this change because
-ftrapping-math(its default) blocks if-conversion ofregular::index; with-fno-trapping-mathgcc 14 reaches the same 0.8 ns/element with this patch. A branch-free rewrite ofregular::indexdid not help gcc, since it also treats the int/double conversions as trapping.