Skip to content

[improvement](build) Upgrade Snappy to 1.2.1 and enable SIMD paths - #67727

Merged
yiguolei merged 2 commits into
apache:masterfrom
HappenLee:pr/snappy-1.2.1
Sep 10, 2026
Merged

[improvement](build) Upgrade Snappy to 1.2.1 and enable SIMD paths#67727
yiguolei merged 2 commits into
apache:masterfrom
HappenLee:pr/snappy-1.2.1

Conversation

@HappenLee

@HappenLee HappenLee commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Doris builds Snappy 1.1.10 without enabling its available SIMD paths. Upgrade to 1.2.1 and match the BE instruction-set target:

  • On x86_64, enable SSE4.2, including Snappy's byte-shuffle and CRC32 hashing paths. Add -mavx2 by default and when USE_AVX2 is enabled; USE_AVX2=0 or OFF selects the SSE4.2 baseline. This follows the existing third-party USE_AVX2 convention used by CRoaring.
  • On ARM, enable CRC32 through ARM_MARCH (default armv8-a+crc).

Snappy is a prebuilt static library, so its third-party build must use the same target as the BE. Changing only the BE's USE_AVX2 setting does not rebuild or retarget an existing Snappy archive. We do not enable SNAPPY_REQUIRE_AVX2, because upstream 1.2.1 adds BMI2 through that option on GCC/Clang, while BMI2 is not guaranteed by AVX2.

Preserve RTTI for SnappySlicesSource and remove the sign-compare patch already included upstream. Existing codec interfaces and default compression selection remain unchanged; bRPC's embedded butil::snappy is outside this change.

Add coverage for binary data, 64 KiB boundaries, empty and uneven slices, truncated and invalid streams, insufficient output capacity, and frozen 1.1.10 compressed data. Use byte-exact comparisons in the existing round-trip tests.

Fresh seven-run median CPU-time microbenchmarks on a Xeon Platinum 8457C, using Clang 16.0.6 for all libraries, gave the following throughput changes relative to 1.1.10. Both new targets were built through the updated third-party script. These results replace the measurements for the earlier SSSE3-only recipe.

Input SSE4.2 compression SSE4.2 decompression AVX2 compression AVX2 decompression
1 MiB repeated binary -7.4% +140.5% -0.4% +140.0%
Upstream HTML corpus -27.4% +10.3% -28.8% +21.6%
Upstream URL corpus -10.3% +4.5% -10.3% +0.9%
Upstream geo.protodata -35.2% -3.5% -33.7% +5.0%

Compression regresses on some inputs; this is not a universal speedup. Measurements are single-threaded, pinned to one logical CPU on a shared host, with hot input, preallocated output buffers, and at least 0.1 CPU seconds per sample. Twelve inputs were measured. These are library microbenchmarks, not SQL or ARM performance claims. The larger upstream hash table adds up to 32 KiB of temporary compression memory.

Release note

Upgrade the BE Snappy dependency to 1.2.1 and enable SIMD paths for the selected CPU target. Third-party Snappy builds enable AVX2 by default; use USE_AVX2=0 or OFF for a non-AVX2 BE. Snappy data remains format-compatible; performance and compressed bytes can vary by input.

Check List (For Author)

  • Test:
    • Current recipe: build SSE4.2 and AVX2 libraries through USE_AVX2=OFF/ON thirdparty/build-thirdparty.sh -j 48 snappy with Clang 16.0.6.
    • Current recipe: check 30 architecture/flag combinations, including unset, numeric and textual boolean values and both ARM architecture names.
    • Inspect both archives: CRC32 instructions present in both, no AVX instructions in the SSE4.2 archive, and 256-bit vector instructions in the AVX2 archive. BMI2 detection remains disabled for both.
    • Verify 24 inputs across all 9 encoder/decoder combinations of 1.1.10, 1.2.1 SSE4.2 and 1.2.1 AVX2; run seven-trial compression/decompression microbenchmarks on 12 inputs.
    • Bash syntax, Snappy recipe shfmt and git diff --check pass. ShellCheck introduces no new warnings; 7 existing warnings remain elsewhere in the script.
    • Previous revision: run-be-ut.sh -j 48 --run --filter='BlockCompressionTest.*' passed all 5 tests under ASAN, with build hygiene, clang-format 16 and changed-line clang-tidy passing. These BE tests ran before the Apache-master cherry-pick and before the SSE4.2/AVX2 flag update; they were not rerun for the final targets. CI must validate final BE integration.
    • ARM CRC32 intrinsic code generation was checked in the previous revision; no ARM hardware test performed.
  • Behavior changed:
    • Yes. CPU build flags, compression output and performance can change; the format and codec interfaces remain compatible.
  • Does this need documentation?
    • No. Third-party build behavior is recorded in the changelog.

### What problem does this PR solve?

Issue Number: N/A

Related PR: StarRocks/starrocks#78566

Problem Summary: Doris builds Snappy 1.1.10 without explicitly enabling its
SIMD paths. Upgrade to 1.2.1, enable SSSE3 on x86_64 within the BE's existing
SSE4.2 baseline, and honor ARM_MARCH (default armv8-a+crc) on ARM. Retain RTTI
for SnappySlicesSource and remove the sign-compare patch included upstream.
Reuse the existing codec and test its binary data, block boundaries, empty
slices, malformed streams, output capacity, and frozen 1.1.10 data.

On a Xeon Platinum 8457C, a seven-run median CPU-time microbenchmark of 1 MiB
repeated binary data improved compression by 24.2% and decompression by 126.7%
against 1.1.10 with the prior build flags, using Clang 16.0.6 for both builds.
Results vary by input: HTML compression regressed by 12.4%. These are hot-buffer
library measurements on a shared host, not SQL or ARM performance results.
The upstream larger hash table adds up to 32 KiB of temporary compression memory.

### Release note

Upgrade the BE Snappy dependency to 1.2.1 and enable SIMD paths within the
existing supported CPU baseline. Snappy data remains format-compatible;
performance and compressed bytes can vary by input.

### Check List (For Author)

- Test: Unit Test / Manual test
    - Run run-be-ut.sh -j 48 --run --filter=BlockCompressionTest.* with ASAN: all 5 tests pass.
    - Build Snappy with thirdparty/build-thirdparty.sh -j 48 snappy.
    - Verify both directions of 1.1.10/1.2.1 decoding on 24 inputs each.
    - Run CPU-time compression/decompression microbenchmarks on 12 inputs.
    - Verify AArch64 CRC32 intrinsic code generation (no ARM hardware test).
    - Pass shell syntax, build hygiene, clang-format 16, and changed-line clang-tidy checks.
- Behavior changed: Yes. Compression output and performance may change;
  the data format, codec interfaces, and default compression selection remain compatible.
- Does this need documentation: No.
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@HappenLee

Copy link
Copy Markdown
Contributor Author

/review

@HappenLee

Copy link
Copy Markdown
Contributor Author

run buildall

### What problem does this PR solve?

Problem Summary: The Snappy recipe only enabled SSSE3 and ignored the BE's
USE_AVX2 setting. Build with the existing SSE4.2 baseline when AVX2 is disabled,
and add -mavx2 by default or when enabled. This enables CRC32 hashing and,
for AVX2 builds, vector copy paths without implicitly requiring BMI2.
Document that third-party libraries must be rebuilt with the matching target.

### Release note

Snappy third-party builds now honor USE_AVX2. Use USE_AVX2=0 or OFF for the
SSE4.2 target; the default target enables AVX2. Performance varies by input.

### Check List (For Author)

- Test: Manual test: build both targets with build-thirdparty.sh -j 48 snappy;
  inspect generated instructions; verify 24 inputs across all 9 combinations
  of old/SSE4.2/AVX2 encoders and decoders; run seven-trial microbenchmarks;
  check 30 architecture/flag combinations, Bash syntax, recipe formatting,
  and no new ShellCheck warnings. BE unit tests were not rerun for this update.
- Behavior changed: Yes. Build flags and compression output/performance can
  change; the Snappy wire format remains compatible.
- Does this need documentation: No. Build behavior is recorded in the changelog.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two blocking ISA-selection defects remain in the Snappy build integration.

Review checkpoints:

  • Goal and proof: the dependency/version update and codec tests are focused and the new binary, boundary, malformed-input, capacity, and frozen-1.1.10 oracles are sound, but they do not prove that the final BE links a Snappy archive matching its selected CPU target.
  • Lifecycle and configuration: the static archive has an independent reusable lifetime with no ISA fingerprint or rebuild edge, and the shell parser does not share CMake's boolean semantics. These are the two inline findings.
  • Compatibility and parallel paths: the checksum, source directory, obsolete-patch removal, RTTI, public ABI, raw format, install layout, direct BE import, Arrow SYSTEM selection, and native Linux/macOS branches are otherwise consistent. Hadoop framing and bRPC's separate Snappy path are unchanged.
  • Concurrency and ownership: no new shared mutable state, lock ordering, static-initialization, or ownership defect was found in the synchronous codec path.
  • Performance and error handling: the disclosed working-memory increase and input-dependent compression regressions were considered; malformed/capacity failures propagate correctly and no additional distinct issue survived.
  • Persistence, transactions, FE/BE transport, nullable handling, runtime-dynamic configuration, and observability are not applicable to this build/dependency change.

Validation was review-only as required by the runner: authoritative diff and whole-path inspection, shell syntax, CMake truth-table/compiler-preprocessor checks, checksum/upstream source verification, and the repository build-hygiene check. I did not build BE or run BE unit tests; the PR description also says those tests were not rerun after the final ISA recipe revision.

fi

local snappy_cxx_flags="-O3"
case "$(uname -m)" in

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Tie this ISA-specific archive to the BE target

The installed libsnappy.a is now target-specific, but its lifetime is not tied to the BE target. The published x86/ARM build images run this script with the defaults, while build.sh reuses any complete third-party tree solely by checking the last unrelated library. Consequently build-for-release.sh --noavx2 can compile BE without AVX2 but link this default AVX2 archive; similarly, ARM_MARCH=armv8-a can reuse the default +crc archive. Upstream Snappy 1.2.1 has reachable unconditional _mm256_* operations under __AVX__ and emits ARM CRC instructions when built with +crc. The BE startup check cannot catch the mismatch because its AVX probes are compiled from the BE's own target macros, and the ARM path does not probe CRC. These nominal lower-target packages can therefore SIGILL on the CPUs they are intended to support. Please keep the reusable archive at the baseline, add target-specific variants/runtime dispatch, or fingerprint it and force selection/rebuild whenever the BE target changes.

x86_64)
# Match the BE's SSE4.2 baseline and optional AVX2 target.
snappy_cxx_flags+=" -msse4.2"
case "${USE_AVX2:-ON}" in

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Normalize USE_AVX2 before branching

This case does not use the same truth table as the BE's later if(USE_AVX2) in CMake. CMake treats named boolean constants case-insensitively and also treats N, IGNORE, NOTFOUND, and *-NOTFOUND as false, but values such as USE_AVX2=Off fall through here and add -mavx2 while BE omits it. That creates an AVX2 Snappy archive inside an otherwise non-AVX2 fresh build and can fault at runtime. Please normalize or reject the setting once, or implement the exact CMake false set, so both build stages select the same target.

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 63.42% (29907/47157)
Line Coverage 48.47% (314113/648074)
Region Coverage 43.96% (253271/576129)
Branch Coverage 45.59% (118153/259165)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.42% (34909/45680)
Line Coverage 61.50% (394044/640699)
Region Coverage 57.58% (330476/573926)
Branch Coverage 58.50% (151176/258424)

@yiguolei
yiguolei merged commit 29583a1 into apache:master Sep 10, 2026
44 of 45 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

PR approved by anyone and no changes requested.

@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Sep 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR approved by at least one committer and no changes requested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. dev/4.1.x dev/4.1.x-conflict reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants