Tier 3: integer fast paths for mixed-grid add and cross-grid stores#20
Merged
Conversation
Two of the three Tier-3 follow-ups from the performance pass, both measured with the nanobench suite and gated to be bit-identical: - addition.hpp: mixed integer-aligned / notch-offset operands with a unit-numerator result notch 1/d compute both offsets as pure integer math ((to_value - Lower)*d and raw*widen) instead of the 3-op exact rational branch. New bench row: 146 -> 31 ns, 2107 -> 415 ins (4.7x). Gated on an index-raw result, imax-safe slot counts, and NON-fp operands (a double raw has no integer offset - test_real_exact's oracle caught that during development; a pinning test keeps it out). - assignment.hpp: the non-integer cross-grid store folds Offset + Factor*raw to one integer multiply-add plus the same round_quotient. The gate proves every product (including the worst-case runtime numerator over R's raw range) fits imax AND mirrors round_quotient's internal value-index branch-choice checks, so reduced and unreduced forms take the same branch - bit-identical results incl. negative ties. Bench row: 156 -> 99 ns, 2144 -> 1351 ins. The third follow-up (folding the constant offset math in the remaining rational branch) is intentionally skipped: after the mixed-add path landed that branch only serves rational-raw operands, no benchmark exercises it, and the fold would save one rational op on a path dominated by the rational add itself. Recorded in bench.cpp's known-slow-paths note. tests/test_cross_grid.cpp pins both gates engaged for their shapes and the fp exclusion; docs/performance.md regenerated with the new rows. Verified: full suite green in default + BND_MATH_FIXED configs, fuzz seed 777 x 40k iters clean (128.8M checks), accuracy tables bit-identical, amalgamation + codegen guard green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Implements two of the three Tier-3 follow-ups from the performance pass (#18), both measured with the nanobench suite and gated to be bit-identical to the rational paths they replace.
Mixed integer/notch-offset add (
addition.hpp)With a unit-numerator result notch
1/d, both operand offsets in result-notch units are pure integer math —(to_value − Lower)·dfor the integer-aligned operand,raw·widenfor the notch-offset one — replacing the 3-op exact-rational branch.146 → 31 ns, 2107 → 415 ins (4.7×) on the new bench row (A/B with the gate disabled).
Gated on an index-raw result, imax-safe slot counts, and non-fp operands: a real-backed operand whose result grid drops to integer storage past the 2^53 exactness limit would have its double raw truncated —
test_real_exact's oracle caught exactly that during development, and a[perf-paths]pinning test keeps fp shapes excluded.Affine-folded cross-grid store (
assignment.hpp)The non-integer
Offset + Factor·rawrational chain folds to one integer multiply-add plus the sameround_quotient. The gate proves every product (including the worst-case runtime numerator over R's raw range) fitsimaxand mirrorsround_quotient's internal value-index branch-choice fit checks — rounding is reduction-invariant, but the branch choice is not (negative ties differ across branches), so both forms are forced onto the same branch.156 → 99 ns, 2144 → 1351 ins on the existing
cross-grid assign :: non-integer snaprow (which includes source construction, so the store itself improved more).Third follow-up: intentionally skipped
Folding the constant offset math in the remaining rational branch is dropped: after the mixed-add path lands, that branch only serves rational-raw operands, no benchmark exercises it, and the fold would save one rational op on a path dominated by the rational add itself. Recorded in bench.cpp's known-slow-paths note.
Verification
Full suite green in default +
BND_MATH_FIXEDconfigs (incl. new[perf-paths]pinning tests) · fuzz seed 777 × 40k iters clean (128.8M checks) · accuracy tables bit-identical · amalgamation + codegen guard green ·docs/performance.mdregenerated with the new rows. The armed cachegrind gates (#19) run against this PR.🤖 Generated with Claude Code