perf: enable x86-64-v2 kernels on a native v2 baseline - #1243
Open
anonrig wants to merge 6 commits into
Open
Conversation
Windows 11 24H2, Rocky Linux 9, and RHEL 9 default to x86-64-v2 (SSSE3, SSE4.1, SSE4.2, POPCNT). Compile the existing SSSE3 host and tab/newline scanners with per-function target attributes so baseline x86-64 gcc/clang builds use them, add SSSE3/SSE2 authority-delimiter scans, and expose ADA_X86_64_V2 for a whole-library -march=x86-64-v2 (MSVC /arch:SSE4.2). Fixes #640 Co-authored-by: Yagiz Nizipli <anonrig@users.noreply.github.com>
GCC refused to always_inline SSSE3 kernels into SSE2 callers, and -march=x86-64-v2 hid those helpers behind always_inline so tests could not link. Keep target attributes on the default x86-64 path and give the helpers a standalone symbol in both configurations. Co-authored-by: Yagiz Nizipli <anonrig@users.noreply.github.com>
Merging this PR will not alter performance
Comparing Footnotes
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1243 +/- ##
=======================================
Coverage 63.27% 63.27%
=======================================
Files 39 39
Lines 7705 7705
Branches 3514 3514
=======================================
Hits 4875 4875
Misses 752 752
Partials 2078 2078 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
NEON/SSE2/scalar definitions of has_tabs_or_newline and the authority delimiter scanners were still always_inline, so basic_tests could not link on those targets. Use ADA_X86_64_V2_SIMD on every definition so a standalone symbol is always produced. Co-authored-by: Yagiz Nizipli <anonrig@users.noreply.github.com>
anonrig
marked this pull request as ready for review
August 31, 2026 01:27
CodSpeed flagged SetHash at -12% because the v2 helpers lost always_inline (needed so ARM/macOS tests could link). Short setter inputs never use the SSSE3 window; they paid a call and an inlining- budget hit in the unity TU. Restore ada_really_inline wrappers that stay on the scalar path for <16 bytes and only call a targeted wide kernel for longer strings. Cover the SIMD windows through parse/set_hash instead of private helpers so other TUs do not need exported symbols. Co-authored-by: Yagiz Nizipli <anonrig@users.noreply.github.com>
always_inline wrappers that called targeted SSSE3 kernels in the same ada.cpp translation unit made CodSpeed worse: SetHash went from -12% to -15% and eight other setters regressed. gcc will not inline across that ISA boundary, and the extra target() functions steal the setter inlining budget. Put the wide kernels in simd_x86_64_v2.cpp (same split as percent_encode). Short inputs stay on ada_really_inline scalar wrappers with no target attribute. Also wrap the new parse test so clang-format 22 is happy. Co-authored-by: Yagiz Nizipli <anonrig@users.noreply.github.com>
Forcing SSSE3 via target() into the default SSE2 unity TU changed setter inlining on CodSpeed's x86-64 baseline. SetHash and SetProtocol still regressed after the kernels moved to their own TU, because ADA_SSSE3 was defined globally and the inlined SSE2/scalar helpers became external calls. Do not pretend the default gcc TU is SSSE3. Rocky/RHEL 9 already define __SSSE3__ and compile the existing kernels. On that native v2 baseline, add SSSE3 authority-delimiter scans and SSE4.1 ptest for has_tabs_or_newline. MSVC AVX/SSE4.2 implies the same ISA. ADA_X86_64_V2 applies -march=x86-64-v2 when a distributor wants it. Co-authored-by: Yagiz Nizipli <anonrig@users.noreply.github.com>
Member
|
@anonrig I think that this should be tested. The x64 processors on GH are surely v2 (it is hard or impossible to find processors than are not v2), so testing this flag in CI should work. |
lemire
approved these changes
Sep 1, 2026
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.
Summary
Addresses #640: Windows 11 24H2, Rocky Linux 9, and RHEL 9 default to x86-64-v2 (SSSE3, SSE4.1, SSE4.2, POPCNT). Earlier revisions forced those kernels into default gcc/clang x86-64 builds with
target("ssse3"). That changed the unityada.cppinlining budget on CodSpeed (which compiles the default x86-64 baseline, not v2): SetHash went from −12% to −15% with in-TU wrappers, and was still −7% after moving the kernels to a separate TU.This revision does not pretend the default gcc TU is SSSE3. Rocky/RHEL 9 already define
__SSSE3__and compile the existinghas_tabs_or_newline/ host-delimiter SSSE3 paths. On that native v2 baseline (and on MSVC/arch:SSE4.2or AVX):@/\?) use an SSSE3pshufbnibble table, matching the host-delimiter kernels already onmain.has_tabs_or_newlineuses SSE4.1pteston the common miss path.ADA_X86_64_V2applies-march=x86-64-v2(MSVC/arch:SSE4.2) when a distributor wants that baseline explicitly.Default gcc/clang x86-64 codegen for setters matches
main(SSE2has_tabs, scalar authority tables). Parser / percent-encode keeptarget("ssse3")as onmain. Public API and ABI are unchanged.Test plan
[::1]:8080, tabs/newlines in a 16-byte window (including overlapping tail), andset_hashADA_X86_64_V2off): preprocessor hasADA_SSE2only; 351/351 tests passed (demo/cdemo/fuzzer/singleheader skipped locally)-DADA_X86_64_V2=ON: preprocessor hasADA_SSSE3/ADA_SSE41/ADA_SSE42/ADA_POPCNT; 351/351 tests passedde728283, including lint-and-format, ARM/macOS/MSVC/clang-cl, ABI, sanitizers, fuzzingmain(47 untouched; SetHash / SetProtocol no longer regress)Closes #640