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

[NativeAOT] Investigate AOT size savings opportunities around async #79204

Open
MichalStrehovsky opened this issue Dec 5, 2022 · 4 comments
Open

Comments

@MichalStrehovsky
Copy link
Member

.NET Native had size optimizations in the structuring of the BCL code to avoid unnecessary generic expansions in the async infrastructure.

We lost these when CoreLibs between the projects were unified. We restored some of it (example: dotnet/corert#6913), but there is likely more that we could do. We could study the old optimizations in the history of the CoreRT repo, or do a new investigation. Not sure how much async changed between then and now.

@eerhardt saw that in a sample 20 MB app using npgsql package, 3 MB of stuff come from the CompilerServices namespace and that feels still a bit excessive.

@ghost
Copy link

ghost commented Dec 5, 2022

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

Issue Details

.NET Native had size optimizations in the structuring of the BCL code to avoid unnecessary generic expansions in the async infrastructure.

We lost these when CoreLibs between the projects were unified. We restored some of it (example: dotnet/corert#6913), but there is likely more that we could do. We could study the old optimizations in the history of the CoreRT repo, or do a new investigation. Not sure how much async changed between then and now.

@eerhardt saw that in a sample 20 MB app using npgsql package, 3 MB of stuff come from the CompilerServices namespace and that feels still a bit excessive.

Author: MichalStrehovsky
Assignees: -
Labels:

area-System.Runtime.CompilerServices

Milestone: 8.0.0

@teo-tsirpanis
Copy link
Contributor

Would an API like a RuntimeFeature.IsSizeOptimized property help? Then we could do this:

if (!RuntimeFeature.IsDynamicCodeCompiled && RuntimeFeature.IsSizeOptimized)
{
    // Use the common interface as generic parameter.
}
else
{
    // Use the struct as generic parameter.
}

@MichalStrehovsky
Copy link
Member Author

Would an API like a RuntimeFeature.IsSizeOptimized property help? Then we could do this:

if (!RuntimeFeature.IsDynamicCodeCompiled && RuntimeFeature.IsSizeOptimized)
{
    // Use the common interface as generic parameter.
}
else
{
    // Use the struct as generic parameter.
}

I don't know if any of the optimizations .NET Native had meaningfully affected throughput and would have to be guarded. dotnet/corert#6913 is not something that would really need to be guarded. It helps everywhere (less jitting, less working set).

@eerhardt
Copy link
Member

eerhardt commented Dec 5, 2022

Here's the MstatDumper dump of the npgsql app, in case anyone is interested in the full output.

npgsql-aot-size.txt

And tweaking that code to just dump what is in the System.Runtime.CompilerServices namespace produces:

System.Runtime.CompilerServices.txt

@tannergooding tannergooding modified the milestones: 8.0.0, Future Aug 14, 2023
MichalStrehovsky added a commit to MichalStrehovsky/runtime that referenced this issue Apr 26, 2024
Contributes to dotnet#79204.

I don't know if this will be considered mergeable, but I wanted to at least try something. For apps that use async a lot (like the Stage2 app we use for Goldilocks), the async infrastructure can cost 10% of the entire executable.

Shuffling a couple things in `GetStateMachineBox` I was able to get 0.23% saving. It's miniscule. In general async is death by a thousand papercuts so I don't see a silver bullet.
MichalStrehovsky added a commit that referenced this issue May 2, 2024
Contributes to #79204.

I don't know if this will be considered mergeable, but I wanted to at least try something. For apps that use async a lot (like the Stage2 app we use for Goldilocks), the async infrastructure can cost 10% of the entire executable.

Shuffling a couple things in `GetStateMachineBox` I was able to get 0.23% saving. It's miniscule. In general async is death by a thousand papercuts so I don't see a silver bullet.
michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this issue May 9, 2024
Contributes to dotnet#79204.

I don't know if this will be considered mergeable, but I wanted to at least try something. For apps that use async a lot (like the Stage2 app we use for Goldilocks), the async infrastructure can cost 10% of the entire executable.

Shuffling a couple things in `GetStateMachineBox` I was able to get 0.23% saving. It's miniscule. In general async is death by a thousand papercuts so I don't see a silver bullet.
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this issue May 30, 2024
Contributes to dotnet#79204.

I don't know if this will be considered mergeable, but I wanted to at least try something. For apps that use async a lot (like the Stage2 app we use for Goldilocks), the async infrastructure can cost 10% of the entire executable.

Shuffling a couple things in `GetStateMachineBox` I was able to get 0.23% saving. It's miniscule. In general async is death by a thousand papercuts so I don't see a silver bullet.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants