1024programmer Asp.Net Performance Improvements in .NET 8 — Native AOT & VM & GC & Mono【Translation】

Performance Improvements in .NET 8 — Native AOT & VM & GC & Mono【Translation】

Performance Improvements in .NET 8 — Native AOT & VM & GC & Mono【Translation】

native AOT

Native AOT is released in .NET 7. It causes .NET programs to be compiled at build time into a self-contained executable or library composed entirely of native code: no JIT is required to compile anything at execution time, and in fact, no JIT is included in the compiled program. The result is an application that can have a very small disk footprint, a small memory footprint, and very fast startup times. In .NET 7, the primary supported workload is console applications. Now in .NET 8, a lot of work has been put into making ASP.NET applications perform well when compiled with native AOT, while also reducing overall cost, regardless of application model.

In .NET 8, an important focus is reducing the size of built applications, and the effect is easy to see. Let’s start by creating a new native AOT console application:

dotnet new console -o nativeaotexample -f net7.0
 

This will create a new nativeaotexample directory and add a new “Hello, world” application for .NET 7 to it. Edit the generated nativeaotexample.csproj in two ways:

  • Change net7.0 to net7.0;net8.0 so that we can easily Built for .NET 7 or .NET 8.
  • Add true in ... so that when we dotnet publish, it uses Native AOT .

Now, publish the application for .NET 7. I’m currently targeting Linux for x64, so I’m using linux-x64, but you can use Windows identifiers like win-x64 on Windows, follow:

dotnet publish -f net7.0 -r linux-x64 -c Release
 

This should successfully build the application, producing a standalone executable, we can ls/dir the output directory to see the resulting binary size (here I used ls -s –block-size=k):

p>

12820K /home/stoub/nativeaotexample/bin/Release/net7.0/linux-x64/publish/nativeaotexample
 

So, on .NET 7 on Linux, this “Hello, world” application, including all necessary library support, GC, everything, is ~13Mb. Now, we can do the same thing for .NET 8:

dotnet publish -f net8.0 -r linux-x64 -c Release
 

View the resulting output size again:

1536K /home/stoub/nativeaotexample/bin/Release/net8.0/linux-x64/publish/nativeaotexample
 

Now in .NET 8, that ~13MB has been reduced to ~1.5M! We can also make it smaller using various supported configuration flags. First, we can set the size and speed options introduced in dotnet/runtime#85133 by adding Size to the .csproj. Then, if I don’t need globalization specific code and data, and can use invariant mode, I can add true. Maybe I don’t care if I have a good stack trace if an exception occurs? dotnet/runtime#88235 Added false option. Add all this and republish:

1248K /home/stoub/nativeaotexample/bin/Release/net8.0/linux-x64/publish/nativeaotexample
 

Very good.

Most of these improvements came from a relentless effort that involved cutting 10Kb here and 20Kb there. Here are some examples of reducing these sizes:

  • The Native AOT compiler is required to create various data structures that are then used by the runtime when the application executes. dotnet/runtime#77884 Added support for these data structures, including data structures containing pointers that can be stored into an application and then reactivated at execution time. Even before subsequent PRs expanded it in various ways, this shaved several hundred kilobytes off the application size, both on Windows and Linux (but more on Linux).

  • Every type that has static fields that contain references has associated with it a data structure that contains several pointers. dotnet/runtime#78794 makes these pointers relativistic, saving about 0.5% of the size of the HelloWorld application (at least on Linux, slightly less on Windows). dotnet/runtime#78801 did the same thing with another set of pointers, saving about 1%.

  • dotnet/runtime#79594 Removed some overly aggressive tracing types and methods that required reflection data to be stored about them. This saves another ~32Kb on HelloWorld.

  • In some cases, generic type dictionaries are created even if they are never used and are therefore empty. dotnet/runtime#82591 PendulumReleases are transferred to JIT’s WASM. Dozens of PRs contributed to making jiterpreter a reality for .NET 8, such as dotnet/runtime#82773 which added basic SIMD support, dotnet/runtime#82756 which added basic loop support, and dotnet/runtime#83247 which added basic SIMD support. A control flow optimization channel.

    Let’s see this in action. I created a new .NET 7 Blazor WebAssembly project, added a NuGet reference to the System.IO.Hashing project, and replaced the contents of Counter.razor with the following:

    @page "/counter"
     @using System.Diagnostics;
     @using System.IO.Hashing;
     @using System.Text;
     @using System.Threading.Tasks;
    
     

    .NET 7

    Current time: @_time

    @code { private TimeSpan _time; private void Hash() { var sw = Stopwatch.StartNew(); for (int i = 0; i < 50_000; i++) XxHash64.HashToUInt64(_data); _time = sw.Elapsed; } private byte[] _data = @"Shall I compare thee to a summer's day? Thou art more lovely and more temperate: Rough winds do shake the darling buds of May, And summer's lease hath all too short a date; Sometimes too hot the eye of heaven shines, And often is his gold complexion dimm'd; And every fair from fair sometime declines, By chance or nature's changing course untrimm'd; But thy eternal summer shall not fade, Nor lose possession of that fair thou ow'st; Nor shall death brag thou wander'st in his shade, When in eternal lines to time thou grow'st: So long as men can breathe or eyes can see, So long lives this, and this gives life to thee."u8.ToArray(); }

    Then I did the exact same thing, but for .NET 8 I built them in Release and ran them. When each results page opened, I clicked the “Click me” button (a few times, but the results didn’t change).

    Measurements of the time required for operations in NET 7 and .NET 8 are self-explanatory.

    In addition to jiterpreter, the interpreter itself also has many improvements, such as:

    dotnet/runtime#79165 Added special handling for the stobj IL directive when the value type does not contain any references and therefore does not require interaction with the GC.
    dotnet/runtime#80046 Special handling of brtrue/brfalse comparisons, creating an interpreter opcode for a very common pattern.
    dotnet/runtime#79392 Adds a built-in function for string creation to the interpreter.
    dotnet/runtime#78840 Adds a cache to the Mono runtime (including but not limited to the interpreter) for storing various information about types, such as IsValueType, IsGenericTypeDefinition and IsDelegate.
    dotnet/runtime#81782 added built-in functions for some of the most common operations on Vector128, dotnet/runtime#86859 enhanced this functionality to use the same opcodes for Vector.
    dotnet/runtime#83498 Special handling of division by powers of 2 to use a shift operation instead.
    dotnet/runtime#83490 Adjusted the inlining size limit to ensure that critical methods can be inlined, such as List’s indexer.
    dotnet/runtime#85528 ​​Added deblurring support when sufficient type information is available.

    I’ve mentioned vectorization in Mono several times, but this in itself is a key focus area for all backends in Mono in .NET 8. As of dotnet/runtime#86546, this PR completes Vector128 support for Mono’s AMD64 JIT backend, and all Mono backends now support Vector128. Mono’s WASM backend not only supports Vector128, .NET 8 also includes the new System.Runtime.Intrinsics.Wasm.PackedSimd type, which is specific to WASM and exposes hundreds of overloads that map to WASM SIMD operate. The basis for this type was introduced in dotnet/runtime#73289, where initial SIMD support was added as an internal feature. dotnet/runtime#76539 continues this work by adding more functionality and making types public, as they are now in .NET 8. More than a dozen PRs continued to build it, such as dotnet/runtime#80145 added the ConditionalSelect built-in function, dotnet/runtime#87052 and dotnet/runtime#87828 added the load and store built-in functions, dotnet/runtime#85705 added floating point support, and dotnet/runtime#88595, which reworks surface areas based on learnings since the initial design.

    Another application size-related effort in .NET 8 is reducing reliance on ICU data files (ICU is the globalization library used by .NET and many other systems). Instead, the goal is to rely as much as possible on the target platform’s native APIs (in the case of WASM, the APIs provided by the browser). This effort is called “hybrid globalization” because the dependence on ICU data files is still there, just reduced, and it brings behavioral changes, so it is optional and suitable for those who really want to reduce the size and Willingness to deal with behavioral adaptation situations. Many PRs have also contributed to making this possible for .NET 8, such as dotnet/runtime#81470, dotnet/runtime#84019 and dotnet/runtime#84249. To enable this feature, you can add true to your .csproj. For more information, there is a good design document to dive into.

    Author: Yahle
    Original: http://www.cnblogs.com/yahle
    all rights reserved. When reprinting, the author and original source must be cited in the form of a link.

    Be willing to handle behavioral adaptation situations. Many PRs have also contributed to making this possible for .NET 8, such as dotnet/runtime#81470, dotnet/runtime#84019 and dotnet/runtime#84249. To enable this feature, you can add true to your .csproj. For more information, there is a good design document to dive into.

    Author: Yahle
    Original: http://www.cnblogs.com/yahle
    all rights reserved. When reprinting, the author and original source must be cited in the form of a link.

This article is from the internet and does not represent1024programmerPosition, please indicate the source when reprinting:https://www.1024programmer.com/811348

author: admin

Previous article
Next article

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact Us

Contact us

181-3619-1160

Online consultation: QQ交谈

E-mail: [email protected]

Working hours: Monday to Friday, 9:00-17:30, holidays off

Follow wechat
Scan wechat and follow us

Scan wechat and follow us

Follow Weibo
Back to top
首页
微信
电话
搜索