Skip to content

perf(fmi): drop the cross-slot T1 look-ahead from the seeding drivers - #676

Merged
nh13 merged 1 commit into
mainfrom
perf/fmi-drop-cross-slot-t1-lookahead
Oct 31, 2026
Merged

nh13 merged 1 commit into
mainfrom
perf/fmi-drop-cross-slot-t1-lookahead

Conversation

@nh13

@nh13 nh13 commented Oct 29, 2026 •

Copy link
Copy Markdown

Summary

Both lockstep seeding drivers (SMEM and bwtSeed) issued, after every slot visit, an L2 (_MM_HINT_T1) prefetch for the slot half a batch ahead (slots[(s + N/2) % N]): the two checkpoint blocks that slot would read on its next step. Each slot already hints what its own next step reads into L1, so the look-ahead only repeated those hints, and it paid for them on every visit. This PR removes it. Output is byte-identical.

  • What the look-ahead repeated. A slot that steps next has already T0-prefetched its checkpoint blocks: at the end of its last forward or backward step, in ls_prepare_backward for the first backward step, or when it was filled (ls_prefetch_cp_occ, bsd_prefetch_cp_occ). A slot whose next visit reads something else (a planned jump-table entry from perf(fmi): take the seeding walks' first steps from a jump table #672, the unique-match LF walk or text compare from perf(fmi): compare unique matches with the text and keep their position for SA lookup #670, or nothing once it is done) got a hint for blocks it does not read.
  • What it cost. Every slot visit paid for the target slot's phase test and the mask selects that chose its interval (SMEM driver), or the phase and j test plus a 32-bit % N division (bwtSeed driver), and two prefetch instructions.
  • Removed. ls_prefetch_cp_occ_t1, bsd_prefetch_cp_occ_t1 and their calls. The drivers' comments now say which same-slot prefetch covers each slot's next visit, and the SMEM driver's comment gives the hot slot's actual size (160 bytes). The "Seeding lookahead prefetch" entry under perf: drop coin-flip branches in chaining, ungapped extension and seeding #584 in docs/src/whats-different/performance.md now notes that the prefetch has since been dropped.

Correctness

  • Why it is exact. A prefetch is a hint: it changes no register, memory or control flow the walk reads, so removing one cannot change a seed. The look-ahead's address was computed from the target slot's state but only fed _mm_prefetch.
  • Test suites. Unit suite 568/568, and test/run_unit_tests.sh passes natively on arm64 (bwtSeed lockstep parity 71/71, SMEM lockstep parity 32/32). On an x86-64 build at the AVX2 tier, both lockstep parity tests pass. x86 compile checks pass at -mavx2 and -mavx512f -mavx512bw.
  • End to end. These runs are byte-identical to main (excluding @PG) on arm64 and on an x86 AVX2 build, with the lockstep driver (the default) and with the scalar driver (BWA3_BWTSEED_LOCKSTEP=0), and on arm64 also at lockstep widths of 3 (BWA3_SMEM_LOCKSTEP_N=3, BWA3_BWTSEED_LOCKSTEP_N=3), where the old look-ahead target wrapped: SE, PE and long-read runs with default options, -d 70, -w 30 and --compat=bwa-mem2, and PE with --ks-dedup=on/off, -k 10, -k 30, -y 1, -y 5 and BWA3_BWTSEED_JUMP=0/12.
  • Timing runs. SAM output was identical to main on every timing run on all three hosts.

Timing

Whole aligner, mem -t 16 on a 5M-pair WGS slice (HG00096, 2x150, hg38), clang 19.1.7, index in shared memory, 6 interleaved reps per build in a seeded shuffled order on the same host. This change was measured on its own against main. Figures are the paired per-rep delta vs main (median, bootstrap 95% CI).

host wall CPU (user)
c7i.4xlarge (Sapphire Rapids, AVX-512BW) −2.13% [−2.19, −1.99] −2.08% [−2.17, −2.02]
c6a.4xlarge (Zen 3, AVX2) −1.11% [−2.20, −0.76] −1.13% [−2.21, −0.79]
c8g.4xlarge (Graviton4, NEON) −1.53% [−2.29, −1.08] −1.54% [−2.26, −1.06]

Start-up included: the first 200k pairs of the same slice, -t 16, with the index loaded from the page cache on every run, 12 interleaved reps:

host wall CPU (user)
c7i.4xlarge (Sapphire Rapids, AVX-512BW) −1.07% [−1.07, −0.89] −1.08% [−1.25, −0.88]
c6a.4xlarge (Zen 3, AVX2) −0.80% [−0.96, −0.32] −1.19% [−1.67, −0.81]
c8g.4xlarge (Graviton4, NEON) −0.61% [−0.92, +0.00] −0.32% [−0.54, −0.12]

The 5M-pair runs show the steady-state gain on every tier. A 200k run takes a few seconds, so the timer's 10 ms resolution is 0.3–0.6% of a run and the wall medians sit on that grid; the CPU-time intervals there exclude zero on all three hosts.

Stack

This is the fifth PR of a stacked series that reworks SMEM seeding and SA lookup. It is based on #674 and should be reviewed after it: the comments it rewrites name the jump-table (#672) and unique-match (#670) steps whose own prefetches cover a slot's next visit. The next PR in the series keeps the backward step's loop invariants in registers.

Split out of #656, thanks to @jmschrei for the original work.

Summary by CodeRabbit

  • Performance

    • Updated prefetch behavior in lockstep seeding: cross-slot prefetches were removed, while same-slot prefetches remain.
    • Recorded wall-time measurements for the change.
  • Documentation

    • Clarified which reads the previous prefetch behavior covered and updated stack-usage estimates.

@nh13

nh13 commented Oct 29, 2026

Copy link
Copy Markdown
Author

@coderabbitai pause

@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 45897ef and 538f979.

Files selected for processing: 4
  • docs/src/whats-different/performance.md
  • src/FMI_search.cpp
  • src/FMI_search.h
  • src/lockstep_width.h

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

The lockstep SMEM and bwtSeed drivers no longer issue cross-slot T1 prefetches; same-slot prefetches remain. The private helper declarations and implementations were removed. Comments and performance documentation describe the revised prefetch behavior and update BatchSlot stack-size estimates.

Changes

Lockstep prefetch updates

Layer / File(s) Summary
Remove cross-slot T1 prefetches
src/FMI_search.h, src/FMI_search.cpp, docs/src/whats-different/performance.md
The drivers no longer call the cross-slot T1 prefetch helpers, and the private helper declarations and implementations are removed. Same-slot prefetches remain. Comments and performance documentation describe the prefetch behavior.
Update stack-size estimates
src/FMI_search.cpp, src/lockstep_width.h
Comments update the estimated per-slot hot-state size to 160 B and the estimated worst-case stack frame at width 256 to 43 KB.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Refactor

Possibly related PRs

  • fg-labs/bwa-mem3#626: Changes the lockstep SMEM driver that this PR also modifies. #626 adds same-pass slot retirement and refill; this PR removes cross-slot T1 prefetching from that driver.
Merge Risk: Minimal · previous review 538f9

No actionable merge-blocking risk is identified. The change removes cross-slot prefetch hints without changing the described seeding logic and is mergeable subject to normal checks.

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Public-Repo Hygiene Inconclusive The reviewed diff and commit contain no object-store URL, bucket, account number, instance ID, internal hostname, or machine-local path. Added lines use the public PR URL, clang, and standard CPU/clou… Provide the complete pull-request body and review metadata, or confirm that the omitted body text contains no non-public benchmark, tool, service, bucket, account, hostname, or local path.
Passed Passed checks: 7 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title uses the required Conventional Commits format, names the FMI component and seeding drivers, and accurately describes the removal of cross-slot T1 look-ahead prefetching.
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.
Equivalence Contract Updated Passed PASS: The executable change in src/FMI_search.cpp only removes _MM_HINT_T1 prefetch helpers and their cross-slot calls. It does not modify scoring, tie resolution, MAPQ, flags, tags, CIGAR constru…
Kernel Change Validation Reported Passed The pull request does not modify src/bandedSWA.cpp, src/kswv.cpp, src/ksw.cpp, src/neon_utils.h, or src/simd_compat.h. The conditional documentation requirements do not apply.
Simd Tier Coverage Passed PASS: The diff removes cross-slot _MM_HINT_T1 prefetch helpers and their driver calls. It adds no SSE, AVX, or NEON intrinsic, changes no tier dispatch, and changes no SIMD_WIDTH-dependent buffer.…
Full details: Equivalence Contract Updated

Explanation

PASS: The executable change in src/FMI_search.cpp only removes _MM_HINT_T1 prefetch helpers and their cross-slot calls. It does not modify scoring, tie resolution, MAPQ, flags, tags, CIGAR construction, or record selection. The PR description explicitly states that output is byte-identical and reports verification against main across lockstep and scalar runs. No equivalence-contract update is required.

Full details: Simd Tier Coverage

Explanation

PASS: The diff removes cross-slot _MM_HINT_T1 prefetch helpers and their driver calls. It adds no SSE, AVX, or NEON intrinsic, changes no tier dispatch, and changes no SIMD_WIDTH-dependent buffer. The lockstep_width.h edits are comments only. Existing same-slot _mm_prefetch code remains unchanged.

Full details: Public-Repo Hygiene

Explanation

The reviewed diff and commit contain no object-store URL, bucket, account number, instance ID, internal hostname, or machine-local path. Added lines use the public PR URL, clang, and standard CPU/cloud names. The pull-request body is truncated in the supplied context, and no full body is available in the checkout. Because this check applies to the complete body, the hygiene assessment cannot be complete.

Resolution

Provide the complete pull-request body and review metadata, or confirm that the omitted body text contains no non-public benchmark, tool, service, bucket, account, hostname, or local path.

Finishing Touches
Fix failing CI checks
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@nh13
nh13 force-pushed the perf/fmi-drop-cross-slot-t1-lookahead branch from 4f03d31 to 538f979 Compare October 29, 2026 22:05
@coderabbitai

coderabbitai Bot commented Oct 29, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews paused.

@nh13

nh13 commented Oct 29, 2026

Copy link
Copy Markdown
Author

@coderabbitai pause

@coderabbitai

coderabbitai Bot commented Oct 29, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews paused.

@nh13

nh13 commented Oct 30, 2026

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 30, 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 force-pushed the perf/fmi-bwtseed-reuse-first-walk branch from 45897ef to 26d3936 Compare October 30, 2026 18:11
@nh13
nh13 force-pushed the perf/fmi-drop-cross-slot-t1-lookahead branch from 538f979 to 22f40ac Compare October 30, 2026 18:11
@nh13
nh13 force-pushed the perf/fmi-bwtseed-reuse-first-walk branch from 26d3936 to 6d5dc22 Compare October 30, 2026 22:17
@nh13
nh13 force-pushed the perf/fmi-drop-cross-slot-t1-lookahead branch from 22f40ac to ead8e02 Compare October 30, 2026 22:19
@nh13
nh13 force-pushed the perf/fmi-bwtseed-reuse-first-walk branch from 6d5dc22 to 18c6687 Compare October 30, 2026 22:40
@nh13
nh13 force-pushed the perf/fmi-drop-cross-slot-t1-lookahead branch from ead8e02 to 4b15591 Compare October 30, 2026 22:42
@nh13
nh13 force-pushed the perf/fmi-bwtseed-reuse-first-walk branch from 18c6687 to 2b6fa11 Compare October 31, 2026 01:01
@nh13
nh13 force-pushed the perf/fmi-drop-cross-slot-t1-lookahead branch from 4b15591 to 25a09be Compare October 31, 2026 01:02
@nh13
nh13 force-pushed the perf/fmi-bwtseed-reuse-first-walk branch from 2b6fa11 to 1c83384 Compare October 31, 2026 03:02
Base automatically changed from perf/fmi-bwtseed-reuse-first-walk to main October 31, 2026 03:47
Both lockstep seeding drivers (SMEM and bwtSeed) issued, after every
slot visit, an L2 prefetch of the two checkpoint blocks that the slot
N/2 places further on would read next. For a slot whose next step reads
checkpoint blocks, the hint repeats one already in flight: the slot
T0-prefetched those blocks at the end of its own last step, at slot
init, or (for the first backward step) in ls_prepare_backward. For a
slot whose next visit reads something else (a planned jump-table entry,
the unique-match LF walk or text compare, or nothing once it is done)
it warmed blocks no one reads. It also cost a phase test, mask selects,
and in the bwtSeed driver a 32-bit division per visit. Without it the
whole aligner is faster on all three SIMD tiers measured (AVX-512BW,
AVX2, NEON).

Remove ls_prefetch_cp_occ_t1 and bsd_prefetch_cp_occ_t1 and their
calls. The drivers' comments now say which same-slot prefetch covers
each slot's next visit, the SMEM driver's comment gives the hot slot's
actual size (160 bytes), and the PR #584 entry in performance.md notes
that the look-ahead has since been dropped. Prefetches are hints only,
so output is byte-identical.

Co-authored-by: Jacob Schreiber <jacob.schreiber@umassmed.edu>
@nh13
nh13 force-pushed the perf/fmi-drop-cross-slot-t1-lookahead branch from 25a09be to 4897b39 Compare October 31, 2026 04:32
@nh13

nh13 commented Oct 31, 2026

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Action not completed

No files to review.

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 added this pull request to the merge queue Oct 31, 2026
Merged via the queue into main with commit 2380aa4 Oct 31, 2026
29 checks passed
@nh13
nh13 deleted the perf/fmi-drop-cross-slot-t1-lookahead branch October 31, 2026 09:13
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