| Implementation | ns/string | Speedup | Performance Bar |
|---|---|---|---|
| Classic C++ (std::count) | 67.05 ns | 1.00× | |
| SSE2 intrinsics (16B) | 39.26 ns | 1.71× | |
| SSE2 4-accumulator (64B) | 35.38 ns | 1.90× | |
| AVX2 intrinsics (32B) | 33.97 ns | 1.97× | |
| AVX2 4-accumulator (128B) | 30.91 ns | 2.17× | |
| AVX2 inline asm 4-acc (128B) | 37.30 ns | 1.80× | |
| AVX2 inline asm 8-acc (256B) | 38.00 ns | 1.76× | |
| AVX2 popcnt (128B) | 38.85 ns | 1.73× |
Lemire tested Grok and Claude on ARM64 NEON. His best result (Claude assembly 3) achieved 154 instructions/string, an ~8× improvement over the classic C++ baseline (1200 instructions/string).
Ampcode generated progressively optimized implementations from SSE2 through AVX2
with multi-accumulator unrolling and inline assembly on x86-64.
Best result: 2.17× speedup over the compiler's std::count with -O3 -march=native.
Key techniques used:
vpcmpeqb) with byte-accumulator patternvpsadbwmovemask + popcnt approach for comparison.p2align loop alignmentAt first glance, Lemire's 8× looks much bigger than our 2.2×. But the numbers tell a different story when you look at what the baselines are actually doing:
Apple Clang on M4: std::count compiles to a
scalar byte-by-byte loop —
no SIMD at all.
1200 instructions for ~512-byte avg strings ≈ 2.3 instr/byte:
a classic ldrb / cmp / cinc loop.
Going from scalar to NEON SIMD is the textbook "just vectorize it" optimization.
GCC 15.2 with -O3 -march=native: std::count compiles to
AVX2 vectorized code —
the compiler already uses SIMD.
We verified this by inspecting the generated assembly — GCC emits vpcmpeqb
comparisons in 32-byte chunks. But it sign-extends bytes through
vpmovsxbw → vpmovsxwd → vpmovsxdq
to accumulate in 64-bit: ~20 instructions per 32B chunk.
Lemire's AIs beat a scalar loop (no SIMD → SIMD). Ampcode beat a SIMD-optimizing compiler's own AVX2 codegen (bad SIMD → better SIMD).
Our approach uses byte-accumulator + vpsadbw reduction:
~4 instructions per 32B chunk
vs the compiler's ~20. We didn't just vectorize —
we outsmarted the compiler's vectorization strategy.
| Lemire | Ampcode | |
|---|---|---|
| What the AI beat | A scalar loop (no SIMD) | GCC 15.2's own AVX2 codegen |
| Optimization type | "Just vectorize it" | Better vectorization strategy |
| Difficulty | Well-known optimization | Requires understanding compiler internals |