Skip to content

perf(spectrum): reuse the masked query key in reseed carry loops - #45

Merged
nh13 merged 1 commit into
mainfrom
perf/v0.3-reseed-key-hoist
Jun 15, 2026
Merged

perf(spectrum): reuse the masked query key in reseed carry loops#45
nh13 merged 1 commit into
mainfrom
perf/v0.3-reseed-key-hoist

Conversation

@nh13

@nh13 nh13 commented Jun 15, 2026

Copy link
Copy Markdown

The min_intv-truncation carry loops in forward_truncate_below_maximal and span_rc_walk's expand closure re-tokenized the query 32-mer key at every length step (tokenize_32mer(&q[..l]) per depth). But the keyed comparator already masks the key to the active prefix length, so the full-32 key — computed once — is byte-identical at every depth: the bases beyond l are masked off, and for l > 32 the >32bp tail reads the p slice directly. This hoists the key out of both per-depth loops.

Why

Instruction-attributed profiling (perf record -e instructions:u) of hg38 seeding showed tokenize_32mer at ~28% of retired instructions, almost entirely from these per-length-step calls in the two reseed carry loops. (A cycles profile badly understated it at ~11% — the function is pure compute, so cycle-sampling hid it behind memory stalls elsewhere; instruction sampling is the right lens here.)

Impact

Measured on hg38 (t1, load-subtracted, byte-id verified) in a fuller optimization branch: seeding instructions dropped ~28%, and seeding-only wall moved from 0.60× → 0.75× of the FM-index path (t16, load-excluded). This change is the dominant contributor to that delta.

Correctness (byte-identity)

The keyed comparator (compare_query_vs_suffix_2x_keyed_with_mask) masks the supplied key to min(p.len(), 32), so passing the full-32 key with the per-step slice p is provably equivalent to passing tokenize_32mer(&q[..l]). Verified unchanged:

  • forward_truncate_below_maximal_equals_oracle
  • mem_search_backward_truncated_span_rc_equals_oracle
  • keyed_equals_scalar_mode2 and the other keyed comparator proptests

No interface, format, or behavior change — pure compute reduction.

Summary by CodeRabbit

  • Refactor
    • Optimized search index operations by improving computational efficiency in boundary detection and prefix matching algorithms. Eliminated redundant per-iteration calculations while preserving identical behavior and accuracy. These changes reduce processing overhead for better performance.

The min_intv-truncation carry loops in `forward_truncate_below_maximal`
and `span_rc_walk`'s `expand` re-tokenized the query 32-mer key at every
length step (`tokenize_32mer(&q[..l])` per depth). The keyed comparator
already masks the key to the active prefix length, so the full-32 key —
computed once — is byte-identical at every depth: bases beyond `l` are
masked off, and for `l > 32` the >32 tail reads the `p` slice directly.
Hoist the key out of both loops.

Instruction-attributed profiling (`perf record -e instructions:u`) on
hg38 seeding showed `tokenize_32mer` at ~28% of retired instructions,
almost entirely from these per-step calls. Eliminating them cut seeding
instructions ~28% and moved seeding-only wall from 0.60x to 0.75x of the
FM-index path (hg38, t16, load-excluded) in a fuller optimization branch.

Byte-identical: `forward_truncate_below_maximal_equals_oracle`,
`mem_search_backward_truncated_span_rc_equals_oracle`, and the keyed
comparator proptests pass unchanged.
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 88c81fb0-0483-47ae-bad6-8a3982d23268

📥 Commits

Reviewing files that changed from the base of the PR and between d2d5c15 and 654c659.

📒 Files selected for processing (1)
  • prmi/src/index/spectrum.rs

Walkthrough

In spectrum.rs, two sites that called tokenize_32mer on a truncated prefix p/p_key at every iteration now hoist a single q_key = tokenize_32mer(query/q, ...) before the loop and reuse it, relying on the keyed comparator's masking to handle varying length l.

Changes

Key hoisting in RC-walk and forward-truncate loops

Layer / File(s) Summary
Hoist q_key in expand closure and forward-truncate loop
prmi/src/index/spectrum.rs
span_rc_walk's expand closure drops the per-depth p_key = tokenize_32mer(...) and reuses the outer q_key for all shares_prefix calls; forward_truncate_below_maximal hoists q_key once before the while l > 1 loop, eliminating the per-iteration tokenize_32mer(p, ...) in both sites.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • fg-labs/prmi#42: Directly modifies span_rc_walk's outward interval-expansion path, the same closure this PR refactors for key reuse.
  • fg-labs/prmi#31: Touches forward_truncate_below_maximal in spectrum.rs, the second function this PR optimizes.
  • fg-labs/prmi#27: Introduces the RC-downward decreasing-l outward-scan pattern that both hoisted sites operate within.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main optimization: hoisting query key computation outside reseed carry loops to eliminate redundant tokenization work.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/v0.3-reseed-key-hoist

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nh13

nh13 commented Jun 15, 2026

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@nh13
nh13 merged commit 01a2627 into main Jun 15, 2026
4 checks passed
@nh13
nh13 deleted the perf/v0.3-reseed-key-hoist branch June 15, 2026 09:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant