You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@lucenenet.apache.org by "paulirwin (via GitHub)" <gi...@apache.org> on 2026/07/15 14:58:28 UTC

[I] Explore opportunities for Vector/SIMD performance improvements [lucenenet]

paulirwin opened a new issue, #1423:
URL: https://github.com/apache/lucenenet/issues/1423

   ### Is there an existing issue for this?
   
   - [x] I have searched the existing issues
   
   ### Is your feature request related to a problem? Please describe the problem.
   
   .NET supports [`Vector<T>`](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.vector-1?view=net-10.0) (including back to `net462` via the [System.Numerics.Vectors NuGet package](https://www.nuget.org/packages/System.Numerics.Vectors#readme-body-tab)) and [SIMD intrinsics](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.intrinsics?view=net-10.0) that have the potential to improve performance in some areas of Lucene.NET.
   
   ### Describe the solution you'd like
   
   An initial analysis by Claude Code found the following areas as potentially being able to take advantage of Vector/SIMD.
   
   ## Tier 1: Actually worth doing
   
   ### `FixedBitSet` / `OpenBitSet` / `Int64BitSet` bulk bitwise ops
   
   `Or`, `Xor`, `And`, and `AndNot` are textbook SIMD. `Vector<long>` handles 4 longs/iteration on AVX2, 8 on AVX-512. These run in the hot path of conjunction/disjunction query execution when filters get materialized as bitsets, so it's not micro-benchmark theater. The scalar tail loop pattern is well-understood and low-risk.
   
   ### Cardinality / popcount (`BitUtil.Pop_Intersect`, `Pop_Union`, `Pop_AndNot`, `Pop_Xor`)
   
   These already lean on `.PopCount()` (a JIT intrinsic), but the surrounding loop still walks `long[]` one word at a time computing `a[i] & b[i]` then popcounting. Vector256 AND/OR + a vectorized popcount (or AVX-512 VPOPCNTQ via Avx512.PopCount) is a well-trodden path. Directly speeds up faceting and `intersectionCount`-style filter selectivity checks.
   
   ## Tier 2: Plausible but with caveats
   
   ### Delta / prefix-sum decode (`BlockPackedReaderIterator.cs`, similarity norm decode)
   
   The simple `values[i] += minValue` broadcast-add is trivially vectorizable. But the genuinely hot one, the running prefix sum for doc-ID deltas (`values[i] += values[i-1]`), has a serial dependency and needs the shift-and-add SIMD prefix-sum trick to beat scalar. Doable, more code, smaller/less certain win. I'd only touch it with a benchmark in hand.
   
   ### BytesRef comparison (`StringHelper.BytesDifference`, `Utf8SortedAsUnicodeComparer`)
   
   `Vector<byte>` mismatch-find is a real win for long terms, but terms are often short (< 16 bytes), where SIMD setup cost dominates. Note .NET already gives you `MemoryExtensions.SequenceCompareTo` / `CommonPrefixLength`, which are SIMD-accelerated internally, so the right move here is delegate to the BCL, not hand-roll intrinsics.
   
   ## Tier 3: Don't bother
   
   Packed-int bit unpacking (`BulkOperationPacked1-24`), MurmurHash, and UTF-8 encode all have irregular bit boundaries, state dependencies, or heavy branching. The Java-faithful scalar code is fine there.
   
   ### Additional context
   
   The operations that can use `Vector<T>` can support older targets like `net462` via the NuGet package. This will be JIT-optimized on those platforms but not intrinsic-ified like modern .NET. It still might result in a speed-up, but at least should be as good as the existing code. If benchmarks prove otherwise, we might need to conditionally compile based on a feature flag.
   
   Anything that needs to use the SIMD intrinsics directly will need conditional compilation as that is not available prior to our .NET 8 target.
   
   All of these changes should only be done if benchmarks prove beneficial. Otherwise, it's not worth the increased code complexity.
   
   This is low priority for the 4.8.0 final release, and should not change the API surface.


-- 
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: dev-unsubscribe@lucenenet.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Explore opportunities for Vector/SIMD performance improvements [lucenenet]

Posted by "paulirwin (via GitHub)" <gi...@apache.org>.
paulirwin commented on issue #1423:
URL: https://github.com/apache/lucenenet/issues/1423#issuecomment-6323040521

   Resolved via #1500 and #1501 


-- 
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: dev-unsubscribe@lucenenet.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Explore opportunities for Vector/SIMD performance improvements [lucenenet]

Posted by "paulirwin (via GitHub)" <gi...@apache.org>.
paulirwin closed issue #1423: Explore opportunities for Vector/SIMD performance improvements
URL: https://github.com/apache/lucenenet/issues/1423


-- 
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: dev-unsubscribe@lucenenet.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Explore opportunities for Vector/SIMD performance improvements [lucenenet]

Posted by "paulirwin (via GitHub)" <gi...@apache.org>.
paulirwin commented on issue #1423:
URL: https://github.com/apache/lucenenet/issues/1423#issuecomment-6293656904

   PRs #1500 and #1501 are open that will close out this issue once both are merged.
   
   I had Claude Code (Fable 5.1) do extensive analysis and testing looking for other opportunities, and this is basically it (without i.e. breaking the public API or extensive refactorings that would make future porting efforts difficult). 
   
   Things it checked outside the list above that are already fine:
   - `Arrays.Fill` goes through `Span<T>.Fill`, which is vectorized.
   - `Arrays.Copy` and `ByteBlockPool` reads use `Array.Copy`, which is memcpy.
   - `FixedBitSet.NextSetBit` uses `TrailingZeroCount`, which is a hardware instruction on net8 and net10.
   
   Possible but low-value follow-ups if someone wants to keep digging later:
   - `LZ4.cs` stored-field compression could use SequenceEqual or CommonPrefixLength for match-length extension. It only runs at flush and merge, and upstream Java is scalar there too, so the ceiling is small.
   - `Lucene45DocValuesConsumer` computes min, max and gcd over numeric values at flush. A vector reduction would need System.Numerics.Tensors or hand-written `Vector<long>` code for a cold path.


-- 
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: dev-unsubscribe@lucenenet.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org