From 2204ab2c7860297153c939d2fd3fc90b19b6b148 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Mon, 15 Aug 2022 15:55:23 -0700 Subject: [PATCH 1/3] kestrel perf on high core machines --- aspnetcore/release-notes/aspnetcore-7.0.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/aspnetcore/release-notes/aspnetcore-7.0.md b/aspnetcore/release-notes/aspnetcore-7.0.md index 46708930f0eb..9ebb76dbc778 100644 --- a/aspnetcore/release-notes/aspnetcore-7.0.md +++ b/aspnetcore/release-notes/aspnetcore-7.0.md @@ -29,7 +29,7 @@ The [`IParsable.TryParse`](/dotnet/api/system.iparsable-1.tryparse#system ### Parameter binding with DI in API controllers -Parameter binding for API controller actions binds parameters through [dependency injection](xref:fundamentals/dependency-injection) when the type is configured as a service. This means it’s no longer required to explicitly apply the [`[FromServices]`](xref:Microsoft.AspNetCore.Mvc.FromServicesAttribute) attribute to a parameter. In the following code, both actions return the time: +Parameter binding for API controller actions binds parameters through [dependency injection](xref:fundamentals/dependency-injection) when the type is configured as a service. This means it's no longer required to explicitly apply the [`[FromServices]`](xref:Microsoft.AspNetCore.Mvc.FromServicesAttribute) attribute to a parameter. In the following code, both actions return the time: [!code-csharp[](~/release-notes/aspnetcore-7/samples/ApiController/Controllers/MyController.cs?name=snippet)] @@ -109,7 +109,7 @@ The following code shows the complete `Program.cs` file: Limitations when binding request body to `Stream` or `PipeReader`: * When reading data, the `Stream` is the same object as `HttpRequest.Body`. -* The request body isn’t buffered by default. After the body is read, it’s not rewindable. The stream can't be read multiple times. +* The request body isn't buffered by default. After the body is read, it's not rewindable. The stream can't be read multiple times. * The `Stream` and `PipeReader` aren't usable outside of the minimal action handler as the underlying buffers will be disposed or reused. ### New Results.Stream overloads @@ -122,7 +122,7 @@ For more information, see [Stream examples](xref:fundamentals/minimal-apis?view= ### Typed results for minimal APIs -In .NET 6, the interface was introduced to represent values returned from minimal APIs that don’t utilize the implicit support for JSON serializing the returned object to the HTTP response. The static [Results](/dotnet/api/microsoft.aspnetcore.http.results) class is used to create varying `IResult` objects that represent different types of responses. For example, setting the response status code or redirecting to another URL. The `IResult` implementing framework types returned from these methods were internal however, making it difficult to verify the specific `IResult` type being returned from methods in a unit test. +In .NET 6, the interface was introduced to represent values returned from minimal APIs that don't utilize the implicit support for JSON serializing the returned object to the HTTP response. The static [Results](/dotnet/api/microsoft.aspnetcore.http.results) class is used to create varying `IResult` objects that represent different types of responses. For example, setting the response status code or redirecting to another URL. The `IResult` implementing framework types returned from these methods were internal however, making it difficult to verify the specific `IResult` type being returned from methods in a unit test. In .NET 7 the types implementing `IResult` are public, allowing for type assertions when testing. For example: @@ -187,6 +187,14 @@ One place where these improvements can be noticed is in gRPC, a popular RPC fram ![Entity diagram](https://user-images.githubusercontent.com/219224/177910504-e93579b4-02e4-4079-8a8c-d9d24857aabf.png) +### Kestrel performance improvements on high core machines + +Kestrel uses for many purposes. One purpose is scheduling I/O operations in Kestrel's default Socket transport. Partitioning the `ConcurrentQueue` based on the associated socket reduces contention and increases throughput on machines with many CPU cores. + +There are even higher core machines, such as the 80 core ARM64 Ampere Altra VMs that were recently made available on Azure. Profiling with these machines in .NET 6 showed a lot of contention in one of Kestrel's other `ConcurrentQueue` instances, the `PinnedMemoryPool` that Kestrel uses to cache byte buffers. + +In .NET 7, Kestrel's memory pool is partitioned the same way as its I/O queue, which leads to much lower contention and higher throughput on high core machines. On the 80 core ARM64 VMs, We're seeing over 500% improvement in responses per second (RPS) in the TechEmpower plaintext benchmark. On 48 Core AMD VMs, the improvement is nearly 100% in our HTTPS JSON benchmark. + ## Server ### New ServerReady event for measuring startup time @@ -209,7 +217,7 @@ For more information, see [Shadow copying in IIS](xref:host-and-deploy/iis/advan The console output from dotnet watch has been improved to better align with the logging of ASP.NET Core and to stand out with 😮emojis😍. -Here’s an example of what the new output looks like: +Here's an example of what the new output looks like: ![output for dotnet watch](~/release-notes/aspnetcore-7/static/dnwatch.png) @@ -217,7 +225,7 @@ See [this GitHub pull request](https://github.com/dotnet/sdk/pull/23318) for mor ### Configure dotnet watch to always restart for rude edits -Rude edits are edits that can’t be hot reloaded. To configure dotnet watch to always restart without a prompt for rude edits, set the `DOTNET_WATCH_RESTART_ON_RUDE_EDIT` environment variable to `true`. +Rude edits are edits that can't be hot reloaded. To configure dotnet watch to always restart without a prompt for rude edits, set the `DOTNET_WATCH_RESTART_ON_RUDE_EDIT` environment variable to `true`. ### Developer exception page dark mode From 7bd55446d387a9b25cdf40e4af8fd25600944737 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Tue, 16 Aug 2022 08:34:47 -0700 Subject: [PATCH 2/3] fix capitalization --- aspnetcore/release-notes/aspnetcore-7.0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aspnetcore/release-notes/aspnetcore-7.0.md b/aspnetcore/release-notes/aspnetcore-7.0.md index 9ebb76dbc778..b23354fc1d72 100644 --- a/aspnetcore/release-notes/aspnetcore-7.0.md +++ b/aspnetcore/release-notes/aspnetcore-7.0.md @@ -193,7 +193,7 @@ Kestrel uses for many p There are even higher core machines, such as the 80 core ARM64 Ampere Altra VMs that were recently made available on Azure. Profiling with these machines in .NET 6 showed a lot of contention in one of Kestrel's other `ConcurrentQueue` instances, the `PinnedMemoryPool` that Kestrel uses to cache byte buffers. -In .NET 7, Kestrel's memory pool is partitioned the same way as its I/O queue, which leads to much lower contention and higher throughput on high core machines. On the 80 core ARM64 VMs, We're seeing over 500% improvement in responses per second (RPS) in the TechEmpower plaintext benchmark. On 48 Core AMD VMs, the improvement is nearly 100% in our HTTPS JSON benchmark. +In .NET 7, Kestrel's memory pool is partitioned the same way as its I/O queue, which leads to much lower contention and higher throughput on high core machines. On the 80 core ARM64 VMs, we're seeing over 500% improvement in responses per second (RPS) in the TechEmpower plaintext benchmark. On 48 Core AMD VMs, the improvement is nearly 100% in our HTTPS JSON benchmark. ## Server @@ -257,4 +257,4 @@ The Angular project template has been updated to Angular 14. The React project t ### Manage JSON Web Tokens in development with dotnet user-jwts -The new `dotnet user-jwts` command line tool can create and manage app specific local [JSON Web Tokens](https://jwt.io/introduction) (JWTs). For more information, see [Manage JSON Web Tokens in development with dotnet user-jwts](xref:security/authentication/jwt?view=aspnetcore-7.0&preserve-view=true). \ No newline at end of file +The new `dotnet user-jwts` command line tool can create and manage app specific local [JSON Web Tokens](https://jwt.io/introduction) (JWTs). For more information, see [Manage JSON Web Tokens in development with dotnet user-jwts](xref:security/authentication/jwt?view=aspnetcore-7.0&preserve-view=true). From 72fc215a2234744ee5f044b515447183e5882f3c Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Tue, 16 Aug 2022 12:18:58 -0700 Subject: [PATCH 3/3] Update aspnetcore/release-notes/aspnetcore-7.0.md Co-authored-by: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> --- aspnetcore/release-notes/aspnetcore-7.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/release-notes/aspnetcore-7.0.md b/aspnetcore/release-notes/aspnetcore-7.0.md index f8f3d4854855..ce4958881f3e 100644 --- a/aspnetcore/release-notes/aspnetcore-7.0.md +++ b/aspnetcore/release-notes/aspnetcore-7.0.md @@ -191,7 +191,7 @@ One place where these improvements can be noticed is in gRPC, a popular RPC fram Kestrel uses for many purposes. One purpose is scheduling I/O operations in Kestrel's default Socket transport. Partitioning the `ConcurrentQueue` based on the associated socket reduces contention and increases throughput on machines with many CPU cores. -There are even higher core machines, such as the 80 core ARM64 Ampere Altra VMs that were recently made available on Azure. Profiling with these machines in .NET 6 showed a lot of contention in one of Kestrel's other `ConcurrentQueue` instances, the `PinnedMemoryPool` that Kestrel uses to cache byte buffers. +Profiling on high core machines on .NET 6 showed significant contention in one of Kestrel's other `ConcurrentQueue` instances, the `PinnedMemoryPool` that Kestrel uses to cache byte buffers. In .NET 7, Kestrel's memory pool is partitioned the same way as its I/O queue, which leads to much lower contention and higher throughput on high core machines. On the 80 core ARM64 VMs, we're seeing over 500% improvement in responses per second (RPS) in the TechEmpower plaintext benchmark. On 48 Core AMD VMs, the improvement is nearly 100% in our HTTPS JSON benchmark.