Repository navigation
Add Neoverse-V3 (Graviton5) detection and dispatch - #3374
Conversation
AWS-LC gates its fastest AArch64 implementations (AES-GCM 8x-EOR3,
wide-multiplier Montgomery, batched Keccak) on a microarchitecture
allowlist of Neoverse-V1/V2 and Apple-M. Neoverse-V3 (Graviton5,
MIDR part 0xD84) was not detected, so on Graviton5 the library fell
through to slower fallbacks:
* AES-128-GCM 16KB: 6135 -> 8854 MB/s (+44%, 4x -> 8x-EOR3)
* RSA-2048 sign: 1227 -> 2025 ops/s (+65%, s2n-bignum -> generic)
* RSA-2048 verify: 49986 -> 77819 ops/s (+56%)
* Batched Keccak (SHAKE256-x4): now uses the V-core alt2 kernel
Measured on c9g (Neoverse-V3), all dispatch paths trap-verified.
Changes:
* arm_arch.h: ARMV8_NEOVERSE_V3 bit (1<<18), ARM_CPU_PART_V3 (0xD84);
update CPU-indicator-bit masks 0x7080->0x47080, 0x78fc->0x478fc.
* cpu_aarch64_linux.c: detect V3 MIDR (sets V3 + N1-subset bit).
* cpucap.c: static-armcap support for V3.
* internal.h: add V3 to GCM_8x/wide_multiplier gates + CRYPTO_is_Neoverse_V3();
exclude V3 from is_Neoverse_N1() (V3 is not N1).
* keccak1600.c: group V3 with V1/V2 in both dispatch sites.
* all_tests.json: update CPU-indicator armcap masks to include the V3 bit.
* CI: add linux-graviton5-c9g-2xlarge fleet + graviton5 job.
|
๐ Security Review โ View Report Please review before merging. |
Codecov Reportโ
All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3374 +/- ##
==========================================
- Coverage 78.40% 78.19% -0.22%
==========================================
Files 695 695
Lines 124222 124220 -2
Branches 17265 17261 -4
==========================================
- Hits 97400 97136 -264
- Misses 25899 26162 +263
+ Partials 923 922 -1 โ View full report in Codecov by Harness. ๐ New features to boost your workflow:
|
|
|
||
| #if defined(MY_ASSEMBLER_SUPPORTS_NEON_SHA3_EXTENSION) | ||
| if (CRYPTO_is_Neoverse_V1() || CRYPTO_is_Neoverse_V2()) { | ||
| if (CRYPTO_is_Neoverse_V1() || CRYPTO_is_Neoverse_V2() || CRYPTO_is_Neoverse_V3()) { |
There was a problem hiding this comment.
I am surprised that we see a speedup here. V3 has SHA3 instruction support on all Neon units, and should use the path L450ff (like Apple silicon CPUs)-- or so I thought.
There was a problem hiding this comment.
We investigated and benchmarked V3 on both paths: the SHA3-extension path you're pointing at (L450ff, sha3_keccak2_f1600 run twice) and the V1/V2 grouping (sha3_keccak4_f1600_alt2). Both were trap-verified at the object-code level to confirm the intended kernel actually executed, warmup + 7 reps, SHAKE256-x4 Absorb @ 16 KB:
| core | alt2 (V1/V2 path) |
keccak2 (SHA3-ext path, L450ff) |
delta |
|---|---|---|---|
| V2 (Graviton4) | 264.9 MB/s | 120.8 MB/s | alt2 +119% |
| V3 (Graviton5) | 447.8 MB/s | 413.5 MB/s | alt2 +8.3% |
You're right that V3 closes the gap dramatically โ this is exactly the effect of the improved SHA3 units you describe: the keccak2 SHA3-extension path jumps 120.8 โ 413.5 MB/s (3.4ร) from V2 to V3, so it nearly catches alt2. But alt2 still wins on V3 by ~8%, so grouping V3 with V1/V2 is the (narrowly) faster choice here rather than routing it to the Apple-silicon path. The margin is small enough that if a future V-core flips the ordering we'd want to revisit, but on measured Graviton5 the V-grouping is correct.
(Numbers are on stock c9g / r8g; V3 ~3.29 GHz vs V2 ~2.79 GHz.
There was a problem hiding this comment.
On another note, while looking into your point, I also checked the single-buffer (x1) path on V3, since the same "V3 has full-width SHA3" reasoning could apply there too. To rule out measurement drift on a shared instance, I ran both paths interleaved (A/B/A/B per rep, pinned core, prebuilt trap-verified binaries, 40 reps):
| x1 kernel | V3 (MB/s) |
|---|---|
sha3_keccak_f1600 (scalar lazy-rot, what V3 gets) |
914 |
sha3_keccak_f1600_alt (SHA3-extension) |
832 |
Scalar won 40/40 interleaved reps (+9.9% mean).
The x4 comparison in this thread held up the same way โ alt2 won 40/40 reps (+8.4%) over the SHA3-ext path. So V3 stays grouped with N1/V1/V2 at both x1 and x4.
This doesn't contradict the wider SHA3 units โ the scalar lazy-rotation kernel is just very good on V3's scalar/barrel-shift path โ so I've kept the "SHA3 on 1/4 Neon units" comment scoped to V1/V2.
| // CPU capabilities of N1 are a subset of CPU capabilities of V3 | ||
| OPENSSL_armcap_P |= ARMV8_NEOVERSE_N1; |
There was a problem hiding this comment.
Pre-existing: I think it is confusing to set the NEOVERSE_N1 capability on a CPU that is not an N1. ISTM that one should set at most a one CPU-specific capability (none if the CPU is not detected). If NEOVERSE_N1 is used as an indicator of certain architectural capabilities that all Neoverse cores offer, that deserves a separate helper.
There was a problem hiding this comment.
We resorted to that solution to be able to test N1-specific code paths on a Vx machine in FIPS ACVP testing as detailed in #2815. ACVP testing relies on setting the OPENSSL_armcap environment variable to test the various code paths included in the module.
There was a problem hiding this comment.
Thank you @nebeid!
Rationale: we can think of the N1 capabilities as a subset of those of V1 and V2, so enabling its bit is semantically valid
I can see the motivation, thank you. However, is overloading the CPU capability for N1 the right solution? Now, ARMV8_NEOVERSE_N1 stands both for a specific CPU and for an unspecified set of architecture capabilities. It is also not the case that we are building hierarchical capabilities -- e.g. V2 does not set the V1 capability.
Have you considered introducing a separate capability capturing which aspects of N1 you care about here?
There was a problem hiding this comment.
My understanding is that the V2 and V1 code paths overlap, thus there is (currently) no need for setting the additional flag โ and the same applies to V3.
On the other hand, I am also wondering about the value of setting the V1/V2 flag on V3, in case a new code path is introduced for V3 โ a V3 machine wouldn't otherwise be able to reach and test the V1/V2 code paths. It could be done later when/if needed, but it also could be missed, as it is not obvious that it is needed for the tests. Perhaps we could add a note.
nebeid
left a comment
There was a problem hiding this comment.
Thank you for your review, Hanno.
|
|
||
| #if defined(MY_ASSEMBLER_SUPPORTS_NEON_SHA3_EXTENSION) | ||
| if (CRYPTO_is_Neoverse_V1() || CRYPTO_is_Neoverse_V2()) { | ||
| if (CRYPTO_is_Neoverse_V1() || CRYPTO_is_Neoverse_V2() || CRYPTO_is_Neoverse_V3()) { |
There was a problem hiding this comment.
We investigated and benchmarked V3 on both paths: the SHA3-extension path you're pointing at (L450ff, sha3_keccak2_f1600 run twice) and the V1/V2 grouping (sha3_keccak4_f1600_alt2). Both were trap-verified at the object-code level to confirm the intended kernel actually executed, warmup + 7 reps, SHAKE256-x4 Absorb @ 16 KB:
| core | alt2 (V1/V2 path) |
keccak2 (SHA3-ext path, L450ff) |
delta |
|---|---|---|---|
| V2 (Graviton4) | 264.9 MB/s | 120.8 MB/s | alt2 +119% |
| V3 (Graviton5) | 447.8 MB/s | 413.5 MB/s | alt2 +8.3% |
You're right that V3 closes the gap dramatically โ this is exactly the effect of the improved SHA3 units you describe: the keccak2 SHA3-extension path jumps 120.8 โ 413.5 MB/s (3.4ร) from V2 to V3, so it nearly catches alt2. But alt2 still wins on V3 by ~8%, so grouping V3 with V1/V2 is the (narrowly) faster choice here rather than routing it to the Apple-silicon path. The margin is small enough that if a future V-core flips the ordering we'd want to revisit, but on measured Graviton5 the V-grouping is correct.
(Numbers are on stock c9g / r8g; V3 ~3.29 GHz vs V2 ~2.79 GHz.
| // CPU capabilities of N1 are a subset of CPU capabilities of V3 | ||
| OPENSSL_armcap_P |= ARMV8_NEOVERSE_N1; |
There was a problem hiding this comment.
We resorted to that solution to be able to test N1-specific code paths on a Vx machine in FIPS ACVP testing as detailed in #2815. ACVP testing relies on setting the OPENSSL_armcap environment variable to test the various code paths included in the module.
Group V3 with N1/V1/V2 (x1 scalar) and V1/V2 (x4 SIMD) in the dispatch-logic comments, matching the code. Note that V3's SHA3-extension x4 path is much faster than on V1/V2 but the SIMD path still wins, so V3 stays grouped there. The 'SHA3 on 1/4 Neon units' note is left as V1/V2 only -- V3 has full-width SHA3, and the scalar x1 kernel wins for a different reason (very good on V3's wide scalar/barrel-shift units). Benchmarks (Neoverse-V3, trap-verified, 7 reps): x1 SHA3-256 @16k: scalar 914 vs SHA3-ext 832 MB/s (+9.8%) x4 SHAKE256 @16k: SIMD alt2 448 vs SHA3-ext keccak2 414 MB/s (+8.3%)
|
@nebeid Thank you for digging into this. I missed that V3 has faster Barrel shifter than Apple M cores. It is interesting to note that if scalar ~= Neon, than Note that leave quite a bit of performance on the table here: In We may want evaluate whether it's worth allowing an x3-native version for Keccak in mlx-native. |
### Description of Changes Remove the `linux-graviton5-c9g-2xlarge` CodeBuild fleet and the `graviton5` job added in #3374. Targeted revert of that PR's CI portions only โ the Neoverse-V3 dispatch code stays in place. #### Why The c9g fleet fails to deploy. CodeBuild reserved-capacity fleets do not currently support the c9g (Graviton5) instance family: - The CodeBuild docs' "Supported instance families" list for reserved fleets tops out at `c8g` for compute-optimized (`c6g | c7g | c8g`); no `c9g`. See https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-compute-types.html - A `create_fleet` call with `c9g.2xlarge` returns "The specified instance type is not supported", while the same request with a supported family (`c8g.2xlarge`) succeeds. Graviton5 CI can be re-added once CodeBuild supports a Graviton5 fleet instance family. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. Co-authored-by: Prasanth Dendukuri <prasden@amazon.com>
aws-lc 5.5.0 Created-by: HarmonybrewBot Commit-by: HarmonybrewBot Merged-by: HarmonybrewBot Description: Created by `brew bump` --- Created with `brew bump-formula-pr`.<details> <summary>release notes</summary> <pre>## What's Changed * Restore ADX/AVX2 code paths under OPENSSL_SMALL via new MY_ASSEMBLER_IS_TOO_OLD_FOR_ADX_AVX2 flag by @justsmth in aws/aws-lc#3368 * Include <openssl/cipher.h> from <openssl/hmac.h> for OpenSSL compat by @justsmth in aws/aws-lc#3371 * ci: harden security-review.yml against script injection by @nebeid in aws/aws-lc#3365 * Fix flaky s_client cipher tests by using better ciphers by @justsmth in aws/aws-lc#3373 * chore: simplify the api docs workflow by @dougch in aws/aws-lc#3186 * Add tests for RSASSA-PSS with SHA-3 digest and MGF1 by @WillChilds-Klein in aws/aws-lc#3377 * Link header documentation from README by @WillChilds-Klein in aws/aws-lc#3378 * Rename autofix reasoning role to AwsLcGitHubActionsBedrockRole by @tianyiy-tim in aws/aws-lc#3376 * ci: pin openssh required job by @dougch in aws/aws-lc#3387 * delocate: Drop redundant `-dI` flag by @hanno-becker in aws/aws-lc#3384 * Add Neoverse-V3 (Graviton5) detection and dispatch by @nebeid in aws/aws-lc#3374 * Bump ring from 0.17.8 to 0.17.14 in /tests/ci/lambda by @dependabot[bot] in aws/aws-lc#3375 * Fix docker image dependencies and update octocrab initialization by @prasden in aws/aws-lc#3388 * Update FIPS.md by @justsmth in aws/aws-lc#3382 * Bump urllib3 from 2.6.3 to 2.7.0 in /tests/ci by @dependabot[bot] in aws/aws-lc#3372 * Add MinGW shared-library Windows CI coverage by @justsmth in aws/aws-lc#3398 * Update concurrency in `security-review` by @nhatnghiho in aws/aws-lc#3403 * Enable linker garbage collection for non-FIPS static builds by @justsmth in aws/aws-lc#3397 * Prepare 5.5.0 by @justsmth in aws/aws-lc#3401 ## New Contributors * @tianyiy-tim made their first contribution in aws/aws-lc#3376 **Full Changelog**: https://github.com/aws/aws-lc/compare/v5.4.0...v5.5.0</pre> <p>View the full release notes at <a href="https://github.com/aws/aws-lc/releases/tag/v5.5.0">https://github.com/aws/aws-lc/releases/tag/v5.5.0</a>.</p> </details> <hr> See merge request: Harmonybrew/homebrew-core!15934
Issues
N/A
Description of Changes
Add runtime and static detection of the Neoverse-V3 microarchitecture (Graviton5, MIDR part
0xD84) and group it with Neoverse-V1/V2 for selecting AWS-LC's fastest AArch64 implementations.Why
AWS-LC gates several of its fastest AArch64 code paths on a microarchitecture allowlist (Neoverse-V1/V2, Apple-M). Neoverse-V3 was not on that list, so on Graviton5 the library silently fell through to
slower fallbacks. Measured on a c9g (Neoverse-V3) instance, with every dispatch path trap-verified at the object-code level:
Changes
arm_arch.h: addARMV8_NEOVERSE_V3(bit1<<18) andARM_CPU_PART_V3(0xD84); update the CPU-indicator-bit mask comments (0x7080โ0x47080,0x78fcโ0x478fc).cpu_aarch64_linux.c: detect the V3 MIDR at runtime; set the V3 bit and the N1-subset bit (matching the existing V1/V2 pattern).cpucap.c: static-armcap support viaOPENSSL_STATIC_ARMCAP_NEOVERSE_V3/__ARM_FEATURE_NEOVERSE_V3.internal.h: add V3 to the AES-GCM-8x and wide-multiplier gates; addCRYPTO_is_Neoverse_V3(); exclude V3 fromCRYPTO_is_Neoverse_N1()(since detection also sets the N1-subset bit, V3 must be excluded here or it would be mis-classified as N1 and mis-route Keccak).keccak1600.c: group V3 with V1/V2 at both dispatch sites.all_tests.json: update the CPU-indicator armcap masks used by the "dispatch without CPU indicator bits" tests to include the V3 bit.linux-graviton5-c9g-2xlargeCodeBuild fleet and agraviton5job inlinux_arm_omnibus.yml(mirrors the graviton4 job).Testing
crypto_teston a Neoverse-V3 (c9g) instance; all tests pass and the FIPS module links cleanly.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.