Skip to content

Avoid reducing unused Vector2 and Vector3 elements - #133527

Open
tannergooding wants to merge 1 commit into
dotnet:mainfrom
tannergooding:tannergooding-vector-comparison-codegen
Open

Avoid reducing unused Vector2 and Vector3 elements#133527
tannergooding wants to merge 1 commit into
dotnet:mainfrom
tannergooding:tannergooding-vector-comparison-codegen

Conversation

@tannergooding

Copy link
Copy Markdown
Member

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.

@azure-pipelines

Copy link
Copy Markdown
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.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-numerics
See info in area-owners.md if you want to be subscribed.

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

The new “ignore upper elements” tests are misleading because AsVector2/AsVector3 drop the upper Vector128 lane, so the test inputs don’t actually validate the intended behavior.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 2 Medium severity · 2 Low severity

New issues introduced by this change (4)
Severity Finding
Medium severity src/​libraries/​System.Numerics.Vectors/​tests/​Vector2Tests.cs — This test’s upper parameter doesn’t actually influence any “upper elements” of Vector2:…
Medium severity src/​libraries/​System.Numerics.Vectors/​tests/​Vector3Tests.cs — This test’s upper parameter doesn’t actually affect any stored “upper element” for Vector3:…
Low severity src/​libraries/​System.Private.CoreLib/​src/​System/​Numerics/​Vector2.csinternal static Vector2 Sum(Vector128<float> value) returns a Vector2 (not a scalar sum), which…
Low severity src/​libraries/​System.Private.CoreLib/​src/​System/​Numerics/​Vector3.csinternal static Vector3 Sum(Vector128<float> value) returns a Vector3 (not a scalar sum), which…
What changed in this PR

This PR updates System.Numerics.Vector2/Vector3 reduction-style operations (Sum/Dot/Length/Distance/Normalize/Reflect) to avoid doing 4-lane reductions that effectively incorporate an extra zero lane, keeping intermediate computations in Vector128<float> while reducing only the meaningful elements.

Changes:

  • Replaces Vector128.* reductions for Vector2/Vector3 with custom lane-shuffle reductions that only reduce the meaningful elements.
  • Updates Normalize and Reflect to use the new reduction helpers while keeping intermediates in SIMD form.
  • Expands tests to cover signed-zero behavior and non-finite inputs, and adds targeted reduction-related assertions.
File Description
src/​libraries/​System.Private.CoreLib/​src/​System/​Numerics/​Vector3.cs Reworks reduction-based APIs to reduce only X/Y/Z and avoid the implicit extra lane.
src/​libraries/​System.Private.CoreLib/​src/​System/​Numerics/​Vector2.cs Reworks reduction-based APIs to reduce only X/Y and avoid the implicit extra lane.
src/​libraries/​System.Numerics.Vectors/​tests/​Vector3Tests.cs Adds additional reduction-focused coverage (signed zero, non-finite inputs, reflection/normalization).
src/​libraries/​System.Numerics.Vectors/​tests/​Vector2Tests.cs Adds additional reduction-focused coverage (signed zero, reflection/normalization).

Comment thread src/libraries/System.Numerics.Vectors/tests/Vector2Tests.cs
Comment thread src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs
Comment thread src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs
Comment thread src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 9, 2026 20:19
@tannergooding
tannergooding force-pushed the tannergooding-vector-comparison-codegen branch from 814696c to dc75f3d Compare September 9, 2026 20:19

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Vector2.SumAndBroadcast does not actually broadcast a single computed sum (it can produce lane-dependent NaN payloads) and should be adjusted to replicate one lane’s sum consistently.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity src/​libraries/​System.Private.CoreLib/​src/​System/​Numerics/​Vector2.csSumAndBroadcast currently returns (x + y, y + x) (via AsVector2()), which is not a true…
Issues resolved since last review (4)
Severity Finding
Low severity src/​libraries/​System.Private.CoreLib/​src/​System/​Numerics/​Vector3.csinternal static Vector3 Sum(Vector128&lt;float&gt; value) returns a Vector3 (not a scalar sum), which… View resolved comment
Low severity src/​libraries/​System.Private.CoreLib/​src/​System/​Numerics/​Vector2.csinternal static Vector2 Sum(Vector128&lt;float&gt; value) returns a Vector2 (not a scalar sum), which… View resolved comment
Medium severity src/​libraries/​System.Numerics.Vectors/​tests/​Vector3Tests.cs — This test’s upper parameter doesn’t actually affect any stored “upper element” for Vector3:… View resolved comment
Medium severity src/​libraries/​System.Numerics.Vectors/​tests/​Vector2Tests.cs — This test’s upper parameter doesn’t actually influence any “upper elements” of Vector2:… View resolved comment

Comment thread src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants