feat: add per-lane popcount on batch - #1401
Open
DiamonDinoia wants to merge 1 commit into
Open
Conversation
DiamonDinoia
force-pushed
the
feat/popcount
branch
from
August 13, 2026 15:07
0a717d5 to
9bb2833
Compare
Contributor
|
With the appropriate credits, https://github.com/WojciechMula/sse-popcount seems to provide relevant implementation for arch-specifics |
DiamonDinoia
force-pushed
the
feat/popcount
branch
from
August 13, 2026 19:35
9bb2833 to
5722efd
Compare
Contributor
Author
|
Good point. I also should have listed that the algorithm I implemented I found it on wikipedia. |
DiamonDinoia
force-pushed
the
feat/popcount
branch
from
August 13, 2026 20:15
5722efd to
ca782d8
Compare
Contributor
|
See also https://github.com/kimwalisch/libpopcnt/tree/master based on the paper above for an AVX2 implementation you could add to this PR (with proper credit of course) |
Count the bits set in each element of an integer batch. The common kernel is the SWAR fold; x86 uses the PSHUFB nibble lookup from SSSE3 up, NEON uses CNT with pairwise widening adds, SVE uses svcnt_x, and WASM uses i8x16.popcnt with pairwise widening extends, folding 32-bit counts with a shift-and-add pair for 64-bit elements. VSX and VXE use vec_popcnt, which the compiler maps to a single VPOPCNTB/H/W/D or VPOPCT. For 64-bit elements the two x86 nibble tables carry a +4 and a -4 bias, after libpopcnt, so PSADBW yields the byte count and the 8-byte sum in one instruction. This drops the VPADDB, and measures 1.09x on SSE and AVX2 and 1.05x on AVX-512. avx512vnni gains a 32-bit kernel: VPDPBUSD does in one uop what the VPMADDUBSW and VPMADDWD pair does in two, and the zero accumulator is free because the register copy is eliminated at rename. This measures 1.14x. The same substitution on 256-bit vectors is neutral, since three ports serve them, so avxvnni gets no kernel. The CI job labelled avx512vnni built for knm, which enables avx5124vnniw rather than avx512vnni and selected the avx512pf arch, so it covered neither kernel. It now builds for cascadelake. Assisted-by: Claude Opus 5 <noreply@anthropic.com>
DiamonDinoia
force-pushed
the
feat/popcount
branch
from
August 14, 2026 20:34
ca782d8 to
0bdf5f0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Count the bits set in each element of an integer batch. The common kernel is the SWAR fold; NEON uses CNT with pairwise widening adds, SVE uses svcnt_x, and WASM uses i8x16.popcnt with pairwise widening extends, falling back to the common kernel for 64-bit elements.
I will add kernels in the future too when I have more of this. I need the bitwise operation for a Morton transform library I am writing.
Creating a new file because I plan to add more functions in the future:
countl_zero/countr_zero, bit_reverse, multishift, bit_deposit/bit_extract, bit_permute + bit_permute_constant, bit_matmul, GFNI kernels.
Reviewed by: Claude Opus 5 noreply@anthropic.com