moq-mux: SIMD start-code scanning via memchr#1694
Conversation
Both Annex-B start-code forms share the `00 00 01` suffix (3-byte is `00 00 01`, 4-byte is `00 00 00 01`), so a single SIMD-accelerated substring search for `00 00 01` finds the core. We then peek one byte back to decide whether a leading zero promotes it to a 4-byte code. This replaces the hand-rolled byte-at-a-time scanner with memchr's maintained, stable-Rust, runtime-CPU-feature-detected implementation (SSE2/AVX2/NEON), no unsafe and no nightly. It wins on the large NAL payloads that dominate real bitstreams, where the scan is mostly "no start code for kilobytes". Behavior is unchanged: all 36 existing annexb tests pass, including the consecutive-leading-zeros case where only one zero is promoted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
01d8cbe to
a7dab3b
Compare
WalkthroughThis pull request optimizes Annex-B start code detection in MPEG-TS codec operations. A new memchr dependency (version 2) is added to Cargo.toml, enabling SIMD-accelerated binary pattern matching. The find_start_code function is rewritten to use memchr::memmem to search for the 0x000001 core pattern, then conditionally expands matches preceded by 0x00 into 4-byte start codes, replacing the previous manual byte-skipping logic. The public function signature remains unchanged. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches✨ Simplify code
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. Comment |
Criterion bench comparing the memchr-based find_start_code against the original byte-at-a-time scalar scanner, vendored into the bench as find_start_code_scalar baseline. On this machine: ~4.4x faster finding the first start code in a typical 2KB NAL, and ~44x faster on a worst-case 1MB scan full of `00 00` near-misses that defeat the scalar 3rd-byte skip (1.0 -> 45 GiB/s). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Expands the benchmark to a four-way comparison: naive (byte triplet check), scalar (the original skip scanner), memmem (production), and a memchr variant that scans for the sparse 0x01 byte then does a cheap `00 00` head check. All four are asserted to agree on every input before timing, and a split_all group exercises repeated finds NAL by NAL to expose per-call setup cost. Results are data-dependent: memchr is ~2x faster on zero-heavy data with sparse 0x01, while memmem wins on realistic entropy-coded payload where 0x01 candidates are common. Both stay 4-5x over scalar on the iterator workload. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Keep the simpler memmem-based find_start_code as the production implementation and remove the criterion benchmark, the vendored scalar and naive baselines, and the memchr variant. The four-way comparison served its purpose (confirming the SIMD win); no need to carry it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Replaces the hand-rolled byte-at-a-time Annex-B start-code scanner in
rs/moq-mux/src/codec/annexb.rswith a single SIMD-accelerated substring search.The key insight: both start-code forms share the
00 00 01suffix (3-byte is00 00 01, 4-byte is00 00 00 01). So you don't need a bespoke vectorized scanner that disambiguates 3-vs-4 inline. You do one substring search for the00 00 01core, then peek a single byte backward to see if a leading zero promotes it to 4-byte:This answers the long-standing
TODOin the file (Is this the type of thing that SIMD could further improve?).Why memchr
unsafe, no nightlystd::simd, no#[cfg(target_arch)]matrix to maintain. That matches this repo's "prefer a maintained crate over hand-rolling non-core functionality" rule.memchrwas already in the tree transitively; this just makes it a direct dependency.A criterion benchmark (four-way: naive / scalar / memmem / a memchr-single-byte variant) confirmed the SIMD win: ~4-5x over the old scalar scanner on a realistic iterator workload, and 25-100x on pathological zero-heavy scans. The memmem and memchr variants traded blows depending on byte statistics, so we kept the simpler memmem one. The benchmark is not committed.
Behavior
Unchanged. All 36 existing
annexbtests pass, including:ff 00 00 00 00 00 01), where only one zero is promoted so the result stays(3, 4)and the extra zeros remain outside the code.Public API
find_start_codestayspubwith the same signaturefn(&[u8]) -> Option<(usize, usize)>(the droppedmutis a binding mode, not part of the signature). No breaking change, so this targetsmain.Test plan
cargo test -p moq-mux --lib codec::annexb— 36 passed(Written by Claude)