sgup432 opened a new pull request, #16917: URL: https://github.com/apache/lucene/pull/16917
### Description This idea came up while I was at the Apache Community Over Code :). Currently, the SIMD logic for doc values range queries evaluates values as 64-bit longs, even though they are often bit-packed internally with only 8, 16 or 32 bits per value. With AVX-512 that means we can only compare 8 longs at a time. This change checks whether the values are packed with a byte-aligned width smaller than 64 bits (8, 16 or 32), and if so compares them as bytes, shorts or ints instead. This way, AVX-512 can compare many more values at once: for example, with 16-bit values we can compare 32 shorts at once, and with 8-bit values, 64 bytes at once. Stored values are never negative and always fit in their bit width, so we first narrow the query bounds to that range, which lets them fit in the same small lanes. In addition, the current path reads every value through `LongValues#get` from the memory-mapped input, copies it into the heap (in a `long[]` array), and only then loads it into a vector register for the comparison. This change loads the packed values directly from the memory-mapped index input into vector registers (`ByteVector/ShortVector/IntVector/LongVector.fromMemorySegment`), with no per-value decoding and no heap copy. 64-bit values can't use narrower lanes, but they still benefit from this direct load. #### Implementation We were using `LongValues` to read values but that doesn't tell how values are stored. So I created a new interface `DirectPackedValues` which are implemented by `DirectReader` now. It exposes their bits per value, input and offset. We then use this to take the fast path when the input is memory-mapped, and falls back to the existing code otherwise. Open to feedback if this approach looks okay. Command: ``` ``` #### Benchmark Used existing JMH benchmark `MultiFieldDocValuesRangeBenchmark` we have to compare performance. Done with a single field, 10M docs, and a new `bitsPerValue` parameter, on AVX-512 (c7i.2xlarge,) Ops/s, baseline compare with this change. | Bits/value | Data | Baseline | This PR | Speedup | |---|---|---|---|---| | 8 | random | 57.6 ± 0.2 | 1878.6 ± 87.0 | 32.62× | | 8 | dense | 67.1 ± 0.1 | 1872.7 ± 97.9 | 27.92× | | 16 | random | 57.2 ± 0.2 | 1128.5 ± 8.4 | 19.74× | | 16 | dense | 67.4 ± 0.1 | 1113.0 ± 19.3 | 16.51× | | 24 (no fast path) | random | 54.6 ± 0.2 | 53.7 ± 0.1 | 0.98× | | 24 (no fast path) | dense | 64.0 ± 0.2 | 64.6 ± 0.1 | 1.01× | | 32 | random | 57.6 ± 0.5 | 587.5 ± 4.1 | 10.20× | | 32 | dense | 66.7 ± 0.3 | 651.2 ± 4.3 | 9.76× | | 64 | random | 57.2 ± 0.2 | 162.5 ± 3.0 | 2.84× | | 64 | dense | 67.2 ± 0.2 | 252.5 ± 19.6 | 3.76× | Quite some speedup! <!-- If this is your first contribution to Lucene, please make sure you have reviewed the contribution guide. https://github.com/apache/lucene/blob/main/CONTRIBUTING.md --> -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
