[release/11.0] Avoid reducing unused Vector2 and Vector3 elements - #133607
Merged
Merged
Conversation
Reduce only the meaningful `Vector2` and `Vector3` elements, avoiding zero-extension and extra arithmetic from four-element reductions. Keep intermediates in SIMD form, with scalar reductions for dot products, lengths, and distances, and vector results for normalization and reflection. The implementations use portable `Vector128` operations, without architecture-specific paths. This also preserves negative zero when all summed elements are negative zero, rather than adding an irrelevant positive zero. Adds coverage for signed zero, grouping, nonfinite inputs, and unused upper elements. Addresses the `Vector2`/`Vector3` reduction portion of #133297. `Vector4`, JIT simplifications, and loop alignment are out of scope. ---------- Release x64 codegen for the local `VectorBench` loops, compared with the original upstream implementation: | Method | Before | After | |---|---:|---:| | `LengthSquared2` | 66 bytes | 63 bytes | | `LengthSquared3` | 73 bytes | 67 bytes | | `Normalize3` | 95 bytes | 94 bytes | | `Reflect3` | 117 bytes | 116 bytes | These are whole-method sizes including alignment; the `LengthSquared2` loop itself shrinks from 46 to 30 bytes. The portable `Vector3` broadcast costs five instructions / 25 reduction bytes versus four / 18 for an investigated SSE specialization. In local Ryzen 9 7950X `VectorBench` loops over 1,000 vectors, `Normalize3` was within 1% faster and `Reflect3` was 11-12% slower than that specialization in both runtime orders. This comparison is against the rejected specialization, not upstream; portability is preferred over separate target-specific reduction paths. ARM and WASM performance has not been measured. > [!NOTE] > This description was drafted with GitHub Copilot. --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @dotnet/area-system-numerics |
This was referenced Sep 10, 2026
Open
artl93
approved these changes
Sep 14, 2026
artl93
left a comment
Member
There was a problem hiding this comment.
regression. customer reported. performance. approved.
Clean build analysis required before merge.
Member
|
/ba-g All known and unrelated failures |
Member
The only one build-analysis didn't mark was |
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.
Backport of #133527 to
release/11.0.Customer Impact
This is a performance fix, not a correctness fix.
Customers reported slower
Vector2/Vector3dot products and squared lengths in .NET 11 compared with .NET 10 in #133297. The generated code unnecessarily clears and reduces unused SIMD elements. This fix reduces only the meaningful elements and keeps vector intermediates for normalization and reflection.Local Release x64 codegen shows the
Vector2.LengthSquaredbenchmark loop shrinking from 46 to 30 bytes. This addresses the Vector2/Vector3 reduction portion of the report, not Vector4 or loop alignment; it does not claim to eliminate the entire reported throughput regression.Regression
Reported in .NET 11 Preview 7 relative to .NET 10. The report shows multiply/shuffle/add reductions replacing
dpps, exposing unnecessary work on unused elements. The exact introducing commit has not been established; this backport improves the managed reductions rather than reverting the JIT lowering.Testing
The source change was built locally on Windows x64, and all 7,523
System.Numerics.Vectors.Teststests passed. The added Vector2 nonfinite coverage also passed with hardware intrinsics disabled. Regression coverage includes signed zero, reduction grouping, NaN/infinity, and poisoned unused upper elements where the backend retains those lanes.Only the Vector3 all-negative-zero case is skipped on Mono because its existing intrinsic implementation independently reduces the unused fourth lane. Other scenarios remain enabled. Existing coverage did not explicitly exercise these signed-zero and unused-lane cases; generated-code inspection was needed to identify the redundant arithmetic.
The automated backport applied without conflicts; all four file patches match the merged source change. These local results are for the source change, not a separate release-branch build. Backport CI provides release-branch validation. The source PR's remaining socket and Mono Windows CI failures were unrelated; the Mono crash cluster also occurs on upstream main without this change.
Risk
Low. The change is limited to portable managed Vector2/Vector3 reductions and their tests, with no public API additions, native changes, or architecture-specific implementations. Numerical edge cases are covered explicitly. There is an intentional signed-zero correction: reducing all-negative-zero meaningful elements preserves negative zero instead of adding an irrelevant positive zero.
ARM and WASM performance has not been measured. The portable Vector3 broadcast uses five instructions / 25 reduction bytes rather than four / 18 for a rejected SSE-only alternative; local reflection benchmarks were 11-12% slower than that alternative, not than upstream. The source PR records the full measurements and scope.
IMPORTANT: If this backport is for a servicing release, please verify that:
release/X.0-staging, notrelease/X.0.release/X.0(no-stagingsuffix).Confirmed target:
dotnet/runtime:release/11.0.Package authoring no longer needed in .NET 9
IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.
Note
This backport description was drafted with GitHub Copilot.