PATTERN Cited by 1 source
Accumulator instead of early exit¶
Intent¶
Replace a data-dependent break or early-exit condition in a loop with an OR-accumulator that captures the same signal, tested once after the loop completes. This eliminates the vectorization-blocking control-flow dependency without losing the information the early-exit provided.
Mechanism¶
Before (early-exit, blocks vectorization):
After (accumulator, vectorizable):
let mut high_bit_acc: u8 = 0;
for b in &mut bytes {
high_bit_acc |= *b; // detect any non-ASCII byte
// ... process (branchless)
}
if high_bit_acc & 0x80 != 0 {
// non-ASCII exists somewhere — run fallback
}
The OR-accumulator preserves the high bit of any byte that had it set. After the loop, a single & 0x80 test determines whether any non-ASCII byte was present. The precise location is determined later (via memchr or similar) only when needed.
Why it works¶
A data-dependent loop exit (break) tells the compiler "the trip count depends on the data." The compiler cannot know how many iterations will execute, so it cannot emit a fixed-width SIMD instruction that processes N elements — it might process elements past the exit point.
The accumulator makes the trip count fixed (always bytes.len()), which is exactly the information the auto-vectorizer needs to emit SIMD.
Measured impact¶
On GitHub's casefold benchmark (Apple M4, 5.7 KB ASCII): - With early-exit break: 3.1 GiB/s (0 vector instructions) - With OR-accumulator (same processing): >45 GiB/s (41 vector instructions)
(Source: sources/2026-07-31-github-dont-stop-early-case-folding-source-code-at-memory-speed)
Seen in¶
- sources/2026-07-31-github-dont-stop-early-case-folding-source-code-at-memory-speed — canonical wiki instance
Related¶
- patterns/branchless-sweep-then-check — the broader pattern this enables
- concepts/branchless-programming — the design discipline
- concepts/auto-vectorization — the compiler transform this unblocks