Repository navigation
perf(index): std::simd split with a compaction fallback - #3
Merged
Merged
Conversation
Compares 64 chars per step with std::simd where the standard library has it (libstdc++ 16), otherwise collects the separator indices per 256 char block without a branch per char. The tail is copied into a zero filled block instead of using partial_load: libstdc++ 16 partial_load skips the third char when 4 chars of a register remain (__memcpy_chunks copies bytes 0, 1 and 3). Also renames the compression_index parameter of gen_char_filter_masks.
split moves to lbs::dev. word_ends appends data.size(), so every word is [previous end + 1, end) and filter_and_hash needs no special case for the last word. Renames splits to wordEnds.
codethinki
force-pushed
the
perf/simd-split
branch
from
October 6, 2026 17:16
aa1d9c8 to
01801fa
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.
splitwas the slowest part of loading the word list at runtime (about 1 ms for the 785 KB list on gcc). It only runs at runtime without#embed(msvc) and in the tests and benchmark.split
std::simd::vec<char, 64>compare per 64 chars, indices from the mask withcountr_zeroifper char__cpp_lib_simd || __glibcxx_simd, libstdc++ 16 does not define__cpp_lib_simdyet and clang 23 cannot use its<simd>word_ends
splitmoves tolbs::dev, the publiclbs::word_endsappendsdata.size()as an end sentinel[previous end + 1, end),filter_and_hashno longer special cases the last wordsplitsis renamed towordEndseverywheredev::split,word_endsandfilter_and_hashbefore the implementationsword_endsinstead ofsplitlibstdc++ bug
partial_loaddrops the third char when exactly 4 chars of a register remain,__memcpy_chunksinbits/simd_details.hcopies bytes 0, 1 and 3 in its__bytes >= 2branch. The tail is copied into a zero filled block and loaded withunchecked_loadinstead. Still present on gcc trunk.tests
word_endsagainst a plain loop for every size from 0 to 300, for only separators, for a word without separators and for empty input. This caught the bug above (sizes 4 and 228).results (word list split, pinned core, median of 7)