Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/8.0] Improve performance of UnmanagedMemoryStream #93812

Merged
merged 3 commits into from
Oct 23, 2023

Conversation

github-actions[bot]
Copy link
Contributor

@github-actions github-actions bot commented Oct 21, 2023

Backport of #93766 to release/8.0-staging

/cc @jkotas

Customer Impact

Customer observed very poor performance of UnmanagedMemoryStream on recent Intel hardware in 32-bit processes.

The fix replaces expensive Interlocked operations with an alternative scheme based on Volatile. Up to 50x improvement in UnmanagedMemoryStream microbenchmarks on the affected configuration.

Testing

Verified no functional regression and improved performance of UnmanagedMemoryStream. Microbenchmark submitted to dotnet/performance repo.

Risk

Low

IMPORTANT: If this backport is for a servicing release, please verify that:

  • The PR target branch is release/X.0-staging, not release/X.0.

  • If the change touches code that ships in a NuGet package, you have added the necessary package authoring and gotten it explicitly reviewed.

UnmanagedMemoryStream used Interlocked operations to update its state to prevent tearing of 64-bit values on 32-bit platforms. This pattern is expensive in general and it was found to be prohibitively expensive on recent hardware..

This change removes the expensive Interlocked operations and addresses
the tearing issues in alternative way:
- The _length field is converted to nuint that is guaranteed to be
  updated atomically.
- Writes to _length field are volatile to guaranteed the
  unininitialized memory cannot be read.
- The _position field remains long and it has a risk of tearing. It is
  not a problem since tearing of this field cannot lead to buffer
  overruns.

Fixes #93624
@ghost
Copy link

ghost commented Oct 21, 2023

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

Issue Details

Backport of #93766 to release/8.0-staging

/cc @jkotas

Customer Impact

Testing

Risk

IMPORTANT: If this backport is for a servicing release, please verify that:

  • The PR target branch is release/X.0-staging, not release/X.0.

  • If the change touches code that ships in a NuGet package, you have added the necessary package authoring and gotten it explicitly reviewed.

Author: github-actions[bot]
Assignees: -
Labels:

area-System.IO

Milestone: -

Copy link
Contributor

@artl93 artl93 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved.

@jkotas jkotas changed the base branch from release/8.0-staging to release/8.0 October 23, 2023 18:23
@jkotas jkotas added the Servicing-approved Approved for servicing release label Oct 23, 2023
@jkotas
Copy link
Member

jkotas commented Oct 23, 2023

Approved over email

@jkotas jkotas changed the title [release/8.0-staging] Improve performance of UnmanagedMemoryStream [release/8.0] Improve performance of UnmanagedMemoryStream Oct 23, 2023
@carlossanlop carlossanlop merged commit d8d6927 into release/8.0 Oct 23, 2023
174 of 175 checks passed
@jkotas jkotas deleted the backport/pr-93766-to-release/8.0-staging branch October 23, 2023 20:34
lewing added a commit that referenced this pull request Oct 28, 2023
* [release/8.0] Stable branding for .NET 8 GA

* Handle an empty bandPreleaseVersion

* [release/8.0] Update dependencies from dotnet/emsdk (#93801)

* Update dependencies from https://github.com/dotnet/emsdk build 20231020.2

Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport
 From Version 8.0.0-rtm.23511.3 -> To Version 8.0.0-rtm.23520.2

* switch to the stable version now

* Update dependencies

* Also fix the trigger

* pin the wbt sdk to avoid the latest analizer nonsense

* Use source generation for the serializer

* Try to make sourcebuild happy

* Try again to make sourcebuild happy

* Use reflection and suppress trim analysis instead

This reverts commit 768b65b.

* Fix reverting too much

---------

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: Larry Ewing <lewing@microsoft.com>

* [release/8.0] Update APICompat settings under source build (#93865)

* Update APICompat settings under source build

* Update resolveContract.targets

---------

Co-authored-by: Viktor Hofer <viktor.hofer@microsoft.com>

* Override InformationalVersion for NativeAOT corelib too

* [release/8.0] Improve performance of UnmanagedMemoryStream (#93812)

* Improve performance of UnmanagedMemoryStream

UnmanagedMemoryStream used Interlocked operations to update its state to prevent tearing of 64-bit values on 32-bit platforms. This pattern is expensive in general and it was found to be prohibitively expensive on recent hardware..

This change removes the expensive Interlocked operations and addresses
the tearing issues in alternative way:
- The _length field is converted to nuint that is guaranteed to be
  updated atomically.
- Writes to _length field are volatile to guaranteed the
  unininitialized memory cannot be read.
- The _position field remains long and it has a risk of tearing. It is
  not a problem since tearing of this field cannot lead to buffer
  overruns.

Fixes #93624

* Add comment

---------

Co-authored-by: Jan Kotas <jkotas@microsoft.com>

* Update dependencies from https://github.com/dotnet/emsdk build 20231023.2 (#93881)

Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100
 From Version 8.0.0-rtm.23520.2 -> To Version 8.0.0-rtm.23523.2

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>

* [release/8.0] Update dependencies from dnceng/internal/dotnet-optimization (#93827)

* Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231021.3

optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR
 From Version 1.0.0-prerelease.23519.5 -> To Version 1.0.0-prerelease.23521.3

* Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231021.3

optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR
 From Version 1.0.0-prerelease.23519.5 -> To Version 1.0.0-prerelease.23521.3

---------

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>

* [release/8.0][wasm] Fix perf pipeline runs (#93888)

* Remove --experimental-wasm-eh argument from the wasm_args used for wasm performance runs. (#93357)

(cherry picked from commit a770017)

* performance-setup.sh: Use `release/8.0` as the default channel

* performance-setup.ps1: use release/8.0 as the default channel

* Fix passing wasmArgs for bdn

---------

Co-authored-by: Parker Bibus <parkerbibus@microsoft.com>

* [release/8.0] Honor JsonSerializerOptions.PropertyNameCaseInsensitive in property name conflict resolution. (#93935)

* Honor JsonSerializerOptions.PropertyNameCaseInsensitive in property name conflict resolution.

* Update src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs

Co-authored-by: Jeff Handley <jeffhandley@users.noreply.github.com>

* Address feedback

---------

Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
Co-authored-by: Jeff Handley <jeffhandley@users.noreply.github.com>

* [8.0] Update MsQuic (#93979)

* Try pinning the installer version to a 8.01xx sdk

* Target net8.0 in SatelliteAssemblyFromProjectRef

---------

Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com>
Co-authored-by: Larry Ewing <lewing@microsoft.com>
Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Viktor Hofer <viktor.hofer@microsoft.com>
Co-authored-by: Alexander Köplinger <alex.koeplinger@outlook.com>
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Ankit Jain <radical@gmail.com>
Co-authored-by: Parker Bibus <parkerbibus@microsoft.com>
Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
Co-authored-by: Jeff Handley <jeffhandley@users.noreply.github.com>
@ghost ghost locked as resolved and limited conversation to collaborators Nov 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.IO Servicing-approved Approved for servicing release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants