Skip to content

NEON-vectorized difference - #568

Open
gitRasheed wants to merge 3 commits into
RoaringBitmap:masterfrom
gitRasheed:perf/neon-andnot-shared
Open

gitRasheed wants to merge 3 commits into
RoaringBitmap:masterfrom
gitRasheed:perf/neon-andnot-shared

Conversation

@gitRasheed

@gitRasheed gitRasheed commented Sep 11, 2026

Copy link
Copy Markdown

NEON kernel for difference, the array-container AndNot, on arm64. Both arrays need at least 16 elements. Smaller inputs keep the scalar merge.

The compare core is the intersection kernel's. The new part is deferred emission. A set1 value with no match in the current set2 block may still match a later one, so match bits accumulate in a register and survivors are compacted and stored only when the set1 block retires. The output is always a subset of the set1 elements consumed so far and callers allocate len(set1), so stores need no bounds clamp. When set1 runs out of whole blocks while a set2 block is still held, the kernel skips the held values at or below the retired set1 maximum before handing both tails to the scalar merge.

CRoaring has an x86 version of this operation, difference_vector16.

difference was the largest remaining scalar hotspot among the array set operations, 23 percent of AndNot pipeline time on the real-roaring-datasets corpus. Search indexes call AndNot once per query term to mask deleted documents, and deletion bitmaps are usually array containers.

I made a page that steps through this kernel on worked examples and annotates the assembly line by line, to make the design choices easier to follow: https://claude.ai/code/artifact/5f77af0d-89c2-4965-9d15-95fde361c47f#andnot (the other tabs cover the other three kernels).

Changes

  • setutil_arm64.go: the lane-compaction table, its own commit, shared with NEON-vectorized intersection2by2 #543, NEON-vectorized union2by2 #567 and NEON-vectorized exclusiveUnion2by2 #569.
  • setutil.go / setutil_generic.go: difference, exclusiveUnion2by2 and the two intersection entry points get the generic/arm64 split that union2by2 already has. This commit is shared with NEON-vectorized intersection2by2 #543 and NEON-vectorized exclusiveUnion2by2 #569 so the three merge in any order, and it drops out of the others once one of them lands; the two passthrough files for the other operations are part of it.
  • setutil_andnot_neon_arm64.s: the kernel.
  • setutil_andnot_arm64.go: dispatch and the spill drain for the in-place caller.
  • Tests against the scalar merge: exact- and spare-capacity canaries, the in-place geometry of iandNotArray, three-way self aliasing, duplicate-input store bounds, and one table of direct kernel exits covering every set2 tail length, every skip count, the mask carried into a fast-forward retire, and 65535 as a retired maximum.

Testing

go test passes on Graviton 4 with this branch, and passed on Graviton 5, 4 and 2 with the same kernel on 5 September. go fmt clean. Smat fuzzer, 300 seconds on Graviton 5: 375,187 executions, no failures.

Performance

Against master on Graviton 5 (c9g.xlarge, Neoverse V3), BenchmarkAndNot at a fixed iteration count, medians of five interleaved runs:

BenchmarkAndNot/inPlace=true/left=array/right=array    13793 ns/op -> 1775 ns/op   (7.8x)
BenchmarkAndNot/inPlace=false/left=array/right=array   15022 ns/op -> 2793 ns/op   (5.4x)

Graviton 2 (c6g.large, Neoverse N1): 5.4x in place, 3.7x fresh.

The floor of 16 is where the kernel beats the scalar merge on every measured shape on Neoverse N1, V2 and V3 (sweep of sizes 8 to 96, both input orders, 128 rotated datasets per cell).

union2by2 already has a generic definition and an arm64 one. Give
difference, exclusiveUnion2by2, intersection2by2 and
intersection2by2Cardinality the same split so vector versions can land
one at a time without touching the shared files. The arm64 versions
pass through to the scalar code for now.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant