|
Everett
|
This comparison retains bounded within-word selection, shared construction for select15, NEON validation, and NEON packing for 8- and 16-bit low fields. The encoded arrays and public interfaces are unchanged.
The baseline is 62ead3fab9d0ee5bda1b47780b7905a45aae1182. The integrated candidate is bc24f443cdee7d12492ac8a6f48e8587de0fc147. The runner pins both revisions and builds the same benchmark source; the environment record records the exact header, benchmark, and prototype hashes used for these measurements.
PDEP followed by trailing-zero count. No runtime dispatch or exported ISA flags are added. Rosetta execution validates this branch; native x86 performance remains unmeasured here.select15 uses the existing generic low packer and high-word accumulator. Its samples, exceptions, low/high words, and sentinel retain their layout.The selection precondition is ordinal < popcount(word). Every cumulative byte population is at most 64; the marked subtraction has no cross-byte borrow. Each packing tile consumes exactly eight or four input words and stores one output word. No extra alignment or padding is required.
The existing sparse lookup and scalar dense scan remain. Their first-word mask, 65-word navigation bound, 4096-bit span check, and guarded tail behavior are unchanged. A select15-only consumer now instantiates the shared 64-width packer dispatch; typed consumers already included it. Compile-time cost was not measured.
Apple M2 Max, AppleClang 21, C++20, -O3 -DNDEBUG, strict warnings, QOS_CLASS_USER_INITIATED, without core pinning. Every local build and timing run held both the host cpu-heavy lease and a lease for its build directory.
Each query variant reads the same low/high arrays and matching sample metadata. Inputs are deterministic monotone residuals; every timed query is checked against the original residual array. Current, baseline, fixed-size, and prototype builders produce equal complete encoded checksums. Queries and construction variants rotate order over five trials. Each query trial performs 524,288 lookups through 65,536 shared positions (512 KiB). The high array is tested at both 0 and 8 modulo 64 using identical query positions. Results are resident-memory timings, with allocation, construction, and correctness checks outside query timing.
The hot case has 4,096 entries and 5,376 encoded array bytes; the larger case has 2,097,152 entries and 2,752,512 encoded array bytes. Both have low width 8. These are equal logical inputs and equal encoded layouts, not a claim that the larger index exceeds every cache. The harness also retains source/oracle arrays, metadata copies, and owned build outputs; these are excluded from encoded byte totals, as are C++ object fields and allocator overhead.
Build measurements retain complete owners beyond the timed call, replace the previous owner, and checksum every output array afterward. They include allocation and destruction of the previous result. Packing and validation rows measure those operations separately; validation variants run in fixed order. Their inputs remain resident. No storage I/O or end-to-end store latency is timed.
Medians in nanoseconds; the query rows below use high-array alignment 0 modulo 64. Every CSV also includes minimum/maximum, both alignments, and checksums.
| Operation | Baseline | Retained candidate | Evaluated SIMD scan prototype |
|---|---|---|---|
| Generic select, hot | 38.705 | 29.961 | 36.441 |
| Generic select, larger | 51.300 | 36.274 | 42.919 |
select15, hot | 39.297 | 29.459 | — |
select15, larger | 50.921 | 37.125 | — |
| Generic build, hot, per entry | 1.346 | 1.041 | 1.066 |
| Generic build, larger, per entry | 1.417 | 1.131 | 1.182 |
select15 build, hot, per entry | 3.348 | 1.037 | — |
select15 build, larger, per entry | 3.420 | 1.080 | — |
| Pack width 8, hot, per entry | 0.168 | 0.081 | 0.081 |
| Pack width 16, hot, per entry | 0.230 | 0.124 | 0.121 |
| Pack width 8, larger, per entry | 0.186 | 0.148 | 0.153 |
| Pack width 16, larger, per entry | 0.231 | 0.144 | 0.146 |
| Validate monotonicity, hot, per entry | 0.836 | 0.264 | — |
| Validate monotonicity, larger, per entry | 0.885 | 0.284 | — |
For the generic hot query, the baseline range was 38.135–38.868 ns and the candidate range was 29.179–30.262 ns. Larger ranges were 50.476–52.783 ns and 36.232–38.532 ns. The zero-residual and one-sparse-group fixtures also agree with the oracle; their complete data is retained below. The sparse fixture contains one exceptional group; it does not isolate exception-only lookup latency.
The four-word SIMD population/batch-scan prototype is slower than the retained scalar scan plus bounded word select in these cases. This does not rule out other SIMD select designs. The prototype's width 32 narrowing loop is also excluded: hot packing measured 0.226 ns/entry versus the baseline 0.163, and larger packing 0.245 versus 0.181. Widths1/7/63 are controls whose packing algorithm is unchanged.
The stage-one patch reconstructs the initial broadword and sharing change from the pinned baseline. The prototype patch then reconstructs the evaluated SIMD scan, width 8/16/32 narrowing, and validation. They are benchmark fixtures, not additional production backends. The runner's --prototype option reconstructs both automatically; default runs compare only the baseline and retained implementation.
Rosetta AVX2 medians for generic hot select were 48.498→37.337 ns with BMI2 explicitly disabled, and 46.357→36.932 ns with BMI2 enabled. These are separate translated runs, not native x86 performance or proof of a PDEP speed advantage. The BMI2 executable contains pdepq. No native x86 measurements were obtained for this comparison.
The public EF views pass every 16-bit bitmap in each quarter of a word, full-word selection ordinals, random bitmaps, and exact 1..65-word spans ending at a protected page. Additional cases exercise low widths 0..63, both source and destination packing guards, all short constructor tails, unsigned decreases in every SIMD lane, partial record groups, equal residuals, sparse exceptions, and exact select15/generic encoded agreement against bit-at-a-time oracles.
tests/groups.cc passed in Release and ASan/UBSan on ARM and Rosetta AVX2 with BMI2 enabled and disabled (six executions). Focused Release+ASan CMake/CTest passed groups, rank, front, profile, relocated installation, and embedded consumption (six CTests). Header/source hashes were unchanged during verification.
Run from the repository root, wrapping each command in the host's resource gate with cpu-heavy and the corresponding build-directory lease:
The x86 commands above execute through Rosetta on macOS; only run an ISA target on a host that supports it. The benchmark uses Apple/GNU-style compilers.