8000 perf(l2b): unpack reference via a byte->4-base LUT in l2b_getseq by nh13 · Pull Request #50 · nh13/minibwa · GitHub
[go: up one dir, main page]

Skip to content

perf(l2b): unpack reference via a byte->4-base LUT in l2b_getseq - #50

Draft
nh13 wants to merge 1 commit into
masterfrom
perf/l2b-getseq-lut
Draft

nh13 wants to merge 1 commit into
masterfrom
perf/l2b-getseq-lut

Conversation

@nh13
@nh13 nh13 commented Sep 7, 2026
Copy link
Copy Markdown
Owner

What

l2b_getseq() unpacks a run of 2-bit-packed reference bases into a byte-per-base buffer. Stock unpacks one base per iteration with a shift-and-mask (l2b_get0). This adds a 256-entry lookup table that maps a whole packed byte (4 bases) to its four unpacked bases at once, so the middle of the range is unpacked 4 bases per step with a single aligned uint32 store, falling back to the scalar path for the unaligned head and tail.

The table is a compile-time static const uint32_t[256] — no runtime constructor. Each entry is laid out so that a little-endian uint32 store emits the four bases in ascending position order; that byte-order assumption is enforced with a compile-time #error guard rather than left to silently produce wrong output on a big-endian host. The table is the bulk-unpack equivalent of l2b_get0 (the canonical per-base accessor), cross-referenced in a comment as the packing source of truth.

Correctness — byte-identical to stock (the invariant)

This is an output = identical change. Verified byte-for-byte identical SAM to stock master on hg38 (GRCh38 + ALT/decoy), order-independent comparison, across short-read WGS and long-read HiFi, on multiple independent runs. Also byte-identical on x86 (below). The #error guard makes the little-endian precondition a build-time failure, not a runtime correctness risk, on any non-LE target.

Performance

arm64 (Apple M3 Ultra): short-read WGS wall neutral-to-slightly-positive (~0–1% across runs; earlier low-load measurement was +1.1%), long-read neutral (the table's benefit is proportional to the bulk-unpacked middle run). Precise wall is noise-limited under host load (large-index page-cache variance drives the reference base ~10% run-to-run); the byte-identity gate is the invariant.

x86 (AMD EPYC, AVX2, c6a): byte-identical and non-regressive (~+1.3% short-read WGS).

Review

The little-endian layout assumption is now enforced at compile time (#error guard) instead of relying on host byte order; the table is a compile-time constant with no __attribute__((constructor)) runtime initializer; and it carries a comment tying it to l2b_get0 as the packing definition. A remaining efficiency nitpick (reloading the packed word per iteration) was reviewed and left as-is — the flagged rewrite was not sound.

Notes

Draft, review-only. Downstream-distribution feature vehicle, not a merge target; installation is via the features.toml manifest, tracked separately.

Replace the per-base unpack loop in l2b_getseq() with a head/middle/tail
scheme: scalar bases until 4-base (byte) aligned, then a lookup table that
emits 4 unpacked bases per step, then a scalar tail. The table maps each
packed byte (four 2-bit bases, base 0 in the low bits) to its four unpacked
bases as one little-endian uint32, written with memcpy so an unaligned seq
buffer stays defined behavior. The table is filled once at startup via a
constructor, so there is no per-call setup to amortize -- which is what sank
an earlier word-wise attempt on the short (~162-base) seeding windows.

Portable C, no SIMD and no arch guard, so it helps x86-64 and arm64 alike.
Output is byte-identical to the scalar loop by construction; verified SAM-
identical over full WGS (short-read) and HiFi (long-read) runs. Measured on
an idle M3 Ultra at >=30s per arm: +1.1% short-read wall (reproduced across
reps), long-read neutral.
@nh13 nh13 added feature review vehicle for a manifest feature; never a merge vehicle uninstalled No features.toml block yet; not installed into the distribution (dist). Remove when installed. labels Sep 7, 2026
@coderabbitai
coderabbitai Bot commented Sep 7, 2026 •
Copy link
Copy Markdown

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

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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.

@nh13
nh13 commented Sep 7, 2026
Copy link
Copy Markdown
Owner Author

@coderabbitai pause

@coderabbitai
coderabbitai Bot commented Sep 7, 2026
Copy link
Copy Markdown
✅ Action performed

Reviews paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature review vehicle for a manifest feature; never a merge vehicle uninstalled No features.toml block yet; not installed into the distribution (dist). Remove when installed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0