Skip to content

Expand lane-crossing note in SIMD article with a worked example#54840

Merged
tannergooding merged 2 commits into
dotnet:mainfrom
tannergooding:tannergooding-simd-lane-crossing-example
Jul 21, 2026
Merged

Expand lane-crossing note in SIMD article with a worked example#54840
tannergooding merged 2 commits into
dotnet:mainfrom
tannergooding:tannergooding-simd-lane-crossing-example

Conversation

@tannergooding

@tannergooding tannergooding commented Jul 20, 2026

Copy link
Copy Markdown
Member

What

Expands the lane-crossing [!NOTE] under "Cross-platform vectorization with Vector128" (added in #54834) into a worked example showing why lane-crossing operations don't widen for free on x86/x64, the way element-wise operations do.

Content added

  • Two ASCII diagrams contrasting element-wise Add (same-index, width-agnostic) with a pairwise reduction (adjacent-index, width-sensitive).
  • A verified C# snippet (LaneCrossingExample.cs) with three methods:
    • SumVector128: a correct two-round Sse3.HorizontalAdd reduction on Vector128<float>.
    • SumVector256Naive: the same two-round pattern naively extended to Vector256<float> -- compiles and runs, but only returns the lower lane's partial sum, not the full 8-element total, because Avx.HorizontalAdd repeats the pairwise pattern independently per 128-bit lane.
    • SumVector256: the fix, bridging the lane boundary explicitly with GetLower/GetUpper.
  • A bit-layout diagram (128-bit element-width box) next to the intro paragraph, and a lower/upper split diagram next to the GetLower/GetUpper fix.
  • Wired the three methods into Program.cs's verification runner.

Verification

net11.0 isn't available in this sandbox yet, so the LaneCrossingExample.cs logic was verified in an isolated scratch project targeting net10.0:

SumVector128       = 10 (expect 10)
SumVector256Naive  = 10 (expect 10, only lower lane)
SumVector256       = 110 (expect 110)

Numbers match the prose exactly ([1,2,3,4,10,20,30,40]: lower lane sums to 10, upper lane to 100, naive gives only 10, fixed gives 110).

Scope

Docs-only change to docs/standard/simd.md and the SimdSnippets snippet project. No build/test infra changes. Out of scope (not included here): worked examples for Widen/Narrow/Shuffle, which the article currently only covers in the reference table.


Internal previews

📄 File 🔗 Preview link
docs/standard/simd.md Use SIMD and hardware intrinsics in .NET

Add a worked example under 'Cross-platform vectorization with Vector128'
showing why lane-crossing operations (unlike element-wise ones) don't
widen for free on x86/x64. Includes ASCII diagrams contrasting
element-wise vs. pairwise combination and the Vector128 bit-layout /
lower-upper split, plus a verified LaneCrossingExample.cs snippet
demonstrating a correct Vector128 horizontal reduction, the naive
(wrong) Vector256 extension, and the fix using GetLower/GetUpper.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 20, 2026 21:49
@tannergooding
tannergooding requested review from a team and gewarren as code owners July 20, 2026 21:49
@dotnetrepoman dotnetrepoman Bot added this to the July 2026 milestone Jul 20, 2026
@tannergooding

Copy link
Copy Markdown
Member Author

@gewarren, I'm not sure how we feel about ASCII diagrams in the docs, but this is the bit that I had left out of #54834 and I noticed it when working to simplify the dotnet/runtime repo specific guidance

Gives a visual aid and explanation of one of the other common pitfalls.

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.

Pull request overview

This PR expands the SIMD documentation to better explain why lane-crossing (pairwise/horizontal) operations don’t automatically benefit from widening vectors on x86/x64, by adding diagrams and a worked, verified C# example using Vector128<float> and Vector256<float>.

Changes:

  • Adds ASCII diagrams and an explanatory subsection demonstrating how element-wise operations differ from lane-sensitive horizontal reductions on x86/x64.
  • Introduces a new snippet (LaneCrossingExample.cs) that contrasts a correct Vector128<float> horizontal reduction with a naïve Vector256<float> version and a corrected lane-bridging implementation.
  • Updates the snippet verification runner to execute and print the new example outputs when supported.
Show a summary per file
File Description
docs/standard/snippets/simd/csharp/Program.cs Adds runtime-gated output for the new lane-crossing snippet methods in the verification runner.
docs/standard/snippets/simd/csharp/LaneCrossingExample.cs New snippet showing correct and incorrect horizontal reduction patterns across 128-bit lanes on AVX.
docs/standard/simd.md Expands the x86/x64 lane note into a worked example with diagrams and snippet references.

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 2

Comment thread docs/standard/snippets/simd/csharp/Program.cs Outdated
Comment thread docs/standard/simd.md Outdated
Split the Sse3/Avx gating in the verification runner so the Vector128
demo also runs on SSE3-only hardware without AVX. Add an explicit
'On x86/x64' lead-in where the worked example switches from the
platform-neutral pairwise concept to the x86/x64-specific intrinsics.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@tannergooding
tannergooding merged commit 100fb68 into dotnet:main Jul 21, 2026
9 checks passed
@tannergooding
tannergooding deleted the tannergooding-simd-lane-crossing-example branch July 21, 2026 00:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants