Optimize encoded numeric range bitsets#16160
Conversation
6bdad46 to
281a1f5
Compare
|
Really nice and clever trick. Pushing the query bounds into the encoded domain once so the existing SIMD kernel can run unmodified on packed values is very clean, and the overflow fallback is a nice escape hatch. It also got me thinking about other filter pushdown opportunities. Anywhere we have an invertible monotone transform between stored and decoded values (delta + scale, ordinal dictionaries, scaled values, etc...) the same idea should apply. |
GCD- and delta-encoded dense NumericDocValues can reuse the existing range-into-bitset fast path by transforming query bounds into the encoded domain once per call. Open bounds are saturated so they keep the SIMD path even when the bound transformation would otherwise overflow.
281a1f5 to
82f3c35
Compare
|
@salvatore-campagna Grazie! It took some time to wrap my head around the encoding (wasn't sure I've got the full gist of it). You're right, there might be other places where this recipe might come in handy: rewrite the query bounds in the encoded domain once, hand the encoded ticket scan to the SIMD kernel. |
|
LGTM thanks, I like that it works on open bounds now too. |
|
Good catch @romseygeek — Replaced with a Applied same fix to the sorted-numeric benchmark in #16285. |
|
Reran the benchmark (just on AVX2), the numbers hold. AMD EPYC 7R32 (c5a.2xlarge) — AVX2, 256-bit. JDK 25, 1M docs, 1 fork, 3 iters × 3s.
|
GCD- and delta-encoded dense NumericDocValues can reuse the existing range-into-bitset fast path by transforming query bounds into the encoded domain once per call. Open bounds are saturated so they keep the SIMD path even when the bound transformation would otherwise overflow.
CD- and delta-encoded dense
NumericDocValuescurrently decode every value insiderangeIntoBitSet(), even though the encoded packed values are already available. This PR transforms the query bounds into the encoded domain once per call, then delegates to the existingDocValuesRangeSupportpath.This keeps the implementation provider-neutral: the default scalar provider still works, while the existing Panama Vector API provider can handle the encoded values through the same optimized range-into-bitset path.
Overflow during bound transformation (ArithmeticException _ ) falls back to the previous scalar decoded loop.
The scope is dense singleton numeric doc values.
SortedNumericDocValuesField.newSlowRangeQuerybenefits for singleton fields because Lucene unwraps them toNumericDocValuesbefore usingBatchDocValuesRangeIterator. True multi-valued sorted numerics need a separate value-level-to-doc-level bitset algorithm, but can reuse the same bound transformation idea.Benchmarks
GcdDeltaRangeIntoBitSetBenchmarkPlatform: JDK 25, 1M docs, 1 fork, 3 iters x 2s
default: scalar provider, no --add-modules jdk.incubator.vector panama: SIMD via Panama Vector API
AMD EPYC (c5a.2xlarge, AVX2)
Intel Ice Lake (c6i.2xlarge, AVX-512)
Below a comparison on the gains AVX-512 from larger registers than AVX-2
AVX-512 vs AVX2, Panama provider