Repository navigation
ext/opcache: Use NEON for zend_adler32() on AArch64 - #24721
Open
aran112000 wants to merge 1 commit into
Open
aran112000 wants to merge 1 commit into
aran112000 wants to merge 1 commit into
Conversation
On AArch64, zend_adler32() ran the SSE2 loop through zend_simd.h's SSE2-on-NEON layer, where _mm_madd_epi16() and _mm_sad_epu8() are slow. Use widening multiply-accumulates and pairwise adds instead. The checksum is unchanged, so existing file caches still verify. On an Apple M4 (Linux VM), checksumming 64MB goes from 12GB/s to 24GB/s with GCC 14 or Clang, and from 7.4GB/s to 24GB/s with GCC 11. Assisted-by: Claude
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.
On AArch64, zend_simd.h maps SSE2 to NEON, so zend_adler32() runs the SSE2 loop from #10507 through that layer. _mm_madd_epi16() and _mm_sad_epu8() take several NEON instructions each there, on every 16 bytes. This adds a native NEON loop instead: widening multiply-accumulates for the weighted sum, pairwise adds for the byte sum, and one horizontal add at the end. The result is identical to the scalar and SSE2 versions, so existing file caches still verify, and x86 is unchanged. (dstogov suggested native NEON code for cases like this on #18413.)
Checksumming a 64MB buffer on an Apple M4 (Linux arm64 VM) goes from 12GB/s to 24GB/s with GCC 14 or Clang, and from 7.4GB/s to 24GB/s with GCC 11. Loading 3,876 cached scripts (184MB) from the file cache with the default consistency checks went from 81.8ms to 78.0ms (median of 24 interleaved runs, release build of master, GCC 14).
The new test compares the checksum stored in the .bin header with hash('adler32') of the data, since the existing tests would still pass with a checksum that's consistent but wrong. I checked that it fails when the NEON loop is deliberately broken. I couldn't build the _M_ARM64 branch on Windows.