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

Faster ParseHeaders #39216

Closed
wants to merge 10 commits into from
Closed

Faster ParseHeaders #39216

wants to merge 10 commits into from

Conversation

EgorBo
Copy link
Member

@EgorBo EgorBo commented Dec 28, 2021

Judging by the native traces from Platform-Plaintext TE benchmark (linux-x64) it seems we spend some noticeable time in ParseHeaders:

Linux-x64-Xeon:

image

Linux-arm64-v8.0

image

The current algorithm walks span of data to find "\r\n" and then it tries to extract name and value while doing some validation checks and trimming value. My implementation walks span just once, first it tries to find ":" using a sort of IndexOfAny(span, ':', ' ', '\t', '\n', '\r') function to find ':''s position and makes sure none of illegal symbols come before it. Then, it tries to find \r\n starting from the previously found :'s position. After that we try to trim the value from both sides via plain loops. I assume in most cases the value will only have a single space or tab after ":".

I haven't done Arm64 support (waiting for some feedback on this one first) and haven't tested AVX vs SSE yet, but from what I have here it seems to show quite some stable improvements for Platform-Plaintext (up to +300_000 RPS resulting in 12M requests per second):

                                             baseline                                mychanges               diff
| ---------------------- | ------------------------------------ | ------------------------------------ | ------- |
| CPU Usage (%)          |                                   92 |                                   95 |  +3.26% |
| Cores usage (%)        |                                2,578 |                                2,671 |  +3.61% |
| Working Set (MB)       |                                   38 |                                   37 |  -2.63% |
| Private Memory (MB)    |                                  370 |                                  370 |   0.00% |
| Start Time (ms)        |                                    0 |                                    0 |         |
| First Request (ms)     |                                   64 |                                   59 |  -7.81% |
| Requests/sec           |                           11,671,064 |                           11,988,862 |  +2.72% |
| Requests               |                          176,234,240 |                          180,850,384 |  +2.62% |
| Mean latency (ms)      |                                 1.13 |                                 1.14 |  +0.88% |
| Max latency (ms)       |                                57.24 |                                60.75 |  +6.13% |
| Bad responses          |                                    0 |                                    0 |         |
| Socket errors          |                                    0 |                                    0 |         |
| Read throughput (MB/s) |                             1,402.88 |                             1,443.84 |  +2.92% |
| Latency 50th (ms)      |                                 0.71 |                                 0.69 |  -2.66% |
| Latency 75th (ms)      |                                 1.07 |                                 1.04 |  -2.80% |
| Latency 90th (ms)      |                                 1.74 |                                 1.85 |  +6.32% |
| Latency 99th (ms)      |                                14.66 |                                21.68 | +47.89% |

^ peak RPS for my changes was 12,017,325

This benchmark is quite stable on Linux-x64 server (but Latency's metrics are not🙂) and the improvements show up every run
image

Test methodology

I was using crank like this:

crank --profile aspnet-citrine-lin \
 --application.framework net7.0 \
 --config https://raw.githubusercontent.com/aspnet/Benchmarks/main/scenarios/platform.benchmarks.yml \
 --scenario plaintext \
 --json t1.json \
 --application.options.outputFiles "/path/to/Microsoft.AspNetCore.Server.Kestrel.Core.dll"

where Microsoft.AspNetCore.Server.Kestrel.Core.dll is either a "baseline" or "baseline + my changes"

TODO

  • Run all aspnet benchmarks, not just Platform-Plaintext
  • Compare AVX vs SSE
  • Add Arm64's AdvSimd (mostly, a copy-paste from SSE)
  • Is "1:\r\n"header-value line valid?

Also, I didn't optimize the Multi-span case (where header is split between two reads) but from what I see it happens quite rarely (I can print some statistics from our benchmarks if you need it).

@ghost ghost added the area-runtime label Dec 28, 2021
@jkotas
Copy link
Member

jkotas commented Dec 28, 2021

@EgorBo
Copy link
Member Author

EgorBo commented Dec 28, 2021

Thanks, didn't see those
Waiting for some thoughts on this before I continue then, I don't mind giving up on this if it's against the strategy of removing Unsafe from Kestrel, it was just a weekend project.

@benaadams
Copy link
Member

Couldn't you use the bitmask to refer to the second find, rather than searching again?

i.e. the vector match has found all the matches; so can look at them one after another until run out of matched bits and then vector search again?

@EgorBo
Copy link
Member Author

EgorBo commented Dec 29, 2021

Couldn't you use the bitmask to refer to the second find, rather than searching again?

i.e. the vector match has found all the matches; so can look at them one after another until run out of matched bits and then vector search again?

Not sure I understand, do you mean like if we found ":" let's check what else we found in the current vector?
I guess it's unlikely we'll find '\r' in it as headers are usually not that small.

E.g. for this benchmark we only deal with these:

Accept: application/json,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7
Host: 10.0.0.102:5000
Connection: keep-alive

In real world we might see something like this (Chrome):

Host: 127.0.0.1:5001
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

Ah, for some of them we indeed can see \r in the same vector 🤷‍♂️

@EgorBo
Copy link
Member Author

EgorBo commented Dec 29, 2021

image

This IndexOf(val) next to ParseHeaders is a different beast, it is from SequenceReader::TryReadTo(span, '\n'). After some additional modifications I managed to get + 150_000 RPS more resulting in 12,193,083 RPS. Just FYI.

I'd love to prototype an optimization for JIT someday where for some high-perf primitives like IndexOf, Memmove, etc we will be inserting additional polling in tier0, e.g. int index = ProbeIndexOf(IndexOf(...)); so by the time we promote a method to tier1 we know exactly what kind of values IndexOf usually returns. And if those values are usually big - we might replace IndexOf with IndexOf_HeavilyVectorized and vice versa: small values - we can even inline a simple loop with a fallback, etc.
It should not be difficult to extend existing Dynamic PGO infrastructure to do it.

@sebastienros
Copy link
Member

/benchmark plaintext aspnet-citrine-lin kestrel

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 2, 2022

Benchmark started for plaintext on aspnet-citrine-lin with kestrel

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 2, 2022

Failed to benchmark PR #39216. Skipping... Details:

System.InvalidOperationException: Command cmd.exe /c call .\src\Servers\Kestrel\build.cmd -noBuildJava -noBuildNodeJs -c release -noBuildNative /p:UseIisNativeAssets=false returned exit code 1
   at Microsoft.Crank.PullRequestBot.ProcessUtil.RunAsync(String filename, String arguments, Nullable`1 timeout, String workingDirectory, Boolean throwOnError, IDictionary`2 environmentVariables, Action`1 outputDataReceived, Boolean log, Action`1 onStart, Action`1 onStop, Boolean captureOutput, Boolean captureError, CancellationToken cancellationToken) in D:\a\_work\1\s\crank\src\Microsoft.Crank.PullRequestBot\ProcessUtil.cs:line 188
   at Microsoft.Crank.PullRequestBot.ProcessUtil.RunAsync(String filename, String arguments, Nullable`1 timeout, String workingDirectory, Boolean throwOnError, IDictionary`2 environmentVariables, Action`1 outputDataReceived, Boolean log, Action`1 onStart, Action`1 onStop, Boolean captureOutput, Boolean captureError, CancellationToken cancellationToken) in D:\a\_work\1\s\crank\src\Microsoft.Crank.PullRequestBot\ProcessUtil.cs:line 190
   at Microsoft.Crank.PullRequestBot.Program.RunBenchmark(Command command) in D:\a\_work\1\s\crank\src\Microsoft.Crank.PullRequestBot\Program.cs:line 583
   at Microsoft.Crank.PullRequestBot.Program.RunBenchmark(Command command) in D:\a\_work\1\s\crank\src\Microsoft.Crank.PullRequestBot\Program.cs:line 609
   at Microsoft.Crank.PullRequestBot.Program.Controller(BotOptions options) in D:\a\_work\1\s\crank\src\Microsoft.Crank.PullRequestBot\Program.cs:line 252

@EgorBo
Copy link
Member Author

EgorBo commented Feb 2, 2022

/benchmark plaintext aspnet-citrine-lin kestrel

Wow! Is that a new thing? Can we have it in dotnet/runtime 😄

@sebastienros
Copy link
Member

@EgorBo maybe you should pay attention to your emails ...

@EgorBo
Copy link
Member Author

EgorBo commented Feb 2, 2022

@EgorBo maybe you should pay attention to your emails ...

Oops, I'm sorry, somehow I missed that one 😢

@sebastienros
Copy link
Member

The benchmark failed because of code design rules. I will need to improve the reports to display the build errors if any instead of this random stack trace.

C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(155,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(181,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(185,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(188,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(210,13): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(215,13): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(233,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(247,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(251,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(254,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(266,13): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(293,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(297,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(303,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(309,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(319,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(323,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(327,9): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(335,13): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]
C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Internal\Http\HttpParser.cs(344,13): error IDE0011: Add braces to 'if' statement. [C:\Users\cloudtest\AppData\Local\Temp\aspnetcore\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj]

@EgorBo
Copy link
Member Author

EgorBo commented Feb 3, 2022

The benchmark failed because of code design rules. I will need to improve the reports to display the build errors if any instead of this random stack trace.

will fix the formatting

@EgorBo
Copy link
Member Author

EgorBo commented Feb 3, 2022

/benchmark plaintext aspnet-citrine-lin kestrel

@sebastienros
Copy link
Member

The user 'EgorBo' is not allowed to perform this action.

;) Does it mean you can't actually merge PRs on this repository?

Also I might need to render this message too.

@sebastienros
Copy link
Member

/benchmark plaintext aspnet-citrine-lin kestrel

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 3, 2022

Benchmark started for plaintext on aspnet-citrine-lin with kestrel

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 3, 2022

plaintext - aspnet-citrine-lin

application base head
CPU Usage (%) 99 100 +1.01%
Cores usage (%) 2,781 2,786 +0.18%
Working Set (MB) 127 127 0.00%
Private Memory (MB) 1,150 1,150 0.00%
Build Time (ms) 2,955 2,958 +0.10%
Start Time (ms) 195 199 +2.05%
Published Size (KB) 95,293 95,293 0.00%
.NET Core SDK Version 7.0.100-preview.2.22102.6 7.0.100-preview.2.22102.6
load base head
CPU Usage (%) 94 95 +1.06%
Cores usage (%) 2,631 2,657 +0.99%
Working Set (MB) 37 38 +2.70%
Private Memory (MB) 370 370 0.00%
Start Time (ms) 0 0
First Request (ms) 69 66 -4.35%
Requests/sec 11,791,471 11,807,880 +0.14%
Requests 178,053,200 178,282,139 +0.13%
Mean latency (ms) 1.19 1.34 +12.61%
Max latency (ms) 60.14 66.24 +10.14%
Bad responses 0 0
Socket errors 0 0
Read throughput (MB/s) 1,413.12 1,423.36 +0.72%
Latency 50th (ms) 0.70 0.70 0.00%
Latency 75th (ms) 1.05 1.07 +1.90%
Latency 90th (ms) 1.79 2.08 +16.20%
Latency 99th (ms) 13.47 16.05 +19.15%

@EgorBo
Copy link
Member Author

EgorBo commented Feb 3, 2022

hm.. weird, I did see numbers like 12M with this PR

@halter73 halter73 self-requested a review February 4, 2022 21:36
@halter73
Copy link
Member

halter73 commented Feb 4, 2022

/benchmark plaintext aspnet-citrine-lin kestrel

@halter73
Copy link
Member

halter73 commented Feb 4, 2022

@sebastienros Can we run a benchmark with more request headers? Something like the Chrome headers referenced earlier?

Host: 127.0.0.1:5001
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 5, 2022

Benchmark started for plaintext on aspnet-citrine-lin with kestrel

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 5, 2022

plaintext - aspnet-citrine-lin

application base pr
CPU Usage (%) 99 99 0.00%
Cores usage (%) 2,777 2,773 -0.14%
Working Set (MB) 124 126 +1.61%
Private Memory (MB) 1,150 1,150 0.00%
Build Time (ms) 2,867 2,877 +0.35%
Start Time (ms) 196 198 +1.02%
Published Size (KB) 95,323 95,323 0.00%
.NET Core SDK Version 7.0.100-preview.2.22103.2 7.0.100-preview.2.22103.2
load base pr
CPU Usage (%) 92 95 +3.26%
Cores usage (%) 2,573 2,646 +2.84%
Working Set (MB) 38 38 0.00%
Private Memory (MB) 370 370 0.00%
Start Time (ms) 0 0
First Request (ms) 68 66 -2.94%
Requests/sec 11,723,936 12,032,056 +2.63%
Requests 176,939,232 181,520,283 +2.59%
Mean latency (ms) 1.25 1.12 -10.40%
Max latency (ms) 149.73 46.07 -69.23%
Bad responses 0 0
Socket errors 0 0
Read throughput (MB/s) 1,413.12 1,443.84 +2.17%
Latency 50th (ms) 0.71 0.68 -3.67%
Latency 75th (ms) 1.07 1.02 -4.67%
Latency 90th (ms) 1.81 1.69 -6.63%
Latency 99th (ms) 14.99 12.72 -15.14%

@sebastienros
Copy link
Member

/benchmark plaintext aspnet-citrine-lin,aspnet-citrine-win,aspnet-citrine-amd,aspnet-perf-lin kestrel

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 5, 2022

Benchmark started for plaintext on aspnet-citrine-lin, aspnet-citrine-win, aspnet-citrine-amd, aspnet-perf-lin with kestrel

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 5, 2022

An error occured, please check the logs

@EgorBo
Copy link
Member Author

EgorBo commented Feb 5, 2022

11,723,936 12,032,056 +2.63%

much better 😄

@sebastienros
Copy link
Member

/benchmark plaintext aspnet-citrine-win,aspnet-citrine-amd,aspnet-perf-lin kestrel

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 6, 2022

Benchmark started for plaintext on aspnet-citrine-win, aspnet-citrine-amd, aspnet-perf-lin with kestrel

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 6, 2022

An error occured, please check the logs

@EgorBo
Copy link
Member Author

EgorBo commented Feb 6, 2022

@halter73 so is this PR worth finishing? It almost is, it only reports invalid headers differently so the tests don't like it.

I am asking because of #39216 (comment)

@EgorBo
Copy link
Member Author

EgorBo commented Feb 9, 2022

@sebastienros could you please kick a citrine-arm run? I expect to see 2-3% improvement

@sebastienros
Copy link
Member

/benchmark plaintext aspnet-citrine-arm kestrel

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 9, 2022

Benchmark started for plaintext on aspnet-citrine-arm with kestrel

@pr-benchmarks
Copy link

pr-benchmarks bot commented Feb 9, 2022

plaintext - aspnet-citrine-arm

application base pr
CPU Usage (%) 99 98 -1.01%
Cores usage (%) 3,155 3,150 -0.16%
Working Set (MB) 124 126 +1.61%
Private Memory (MB) 777 779 +0.26%
Build Time (ms) 13,447 16,077 +19.56%
Start Time (ms) 517 557 +7.74%
Published Size (KB) 104,488 104,488 0.00%
.NET Core SDK Version 7.0.100-preview.2.22109.2 7.0.100-preview.2.22109.2
load base pr
CPU Usage (%) 51 51 0.00%
Cores usage (%) 1,416 1,414 -0.14%
Working Set (MB) 38 38 0.00%
Private Memory (MB) 370 370 0.00%
Start Time (ms) 0 0
First Request (ms) 180 167 -7.22%
Requests/sec 6,497,613 6,420,898 -1.18%
Requests 98,112,529 96,951,382 -1.18%
Mean latency (ms) 2.41 2.22 -7.88%
Max latency (ms) 231.51 241.00 +4.10%
Bad responses 0 0
Socket errors 0 0
Read throughput (MB/s) 780.77 771.55 -1.18%
Latency 50th (ms) 1.37 1.38 +0.73%
Latency 75th (ms) 2.29 2.37 +3.49%
Latency 90th (ms) 4.34 4.55 +4.84%
Latency 99th (ms) 15.13 13.53 -10.58%

@sebastienros
Copy link
Member

Good news is that the benchmark worked, right ;)

@EgorBo
Copy link
Member Author

EgorBo commented Feb 9, 2022

btw how do you deal with flaky benchmarks? I see that PlatformPlaintext jumps from 6.67M RPS to 6.3M on arm - it's more than 5% difference 😮

@sebastienros
Copy link
Member

The arm machine we use doesn't produce stable results unfortunately. The ones on INTEL are much more stable. I could add more iterations automatically for ARM but I'd rather just wait for the new machines.

@EgorBo
Copy link
Member Author

EgorBo commented Feb 10, 2022

The arm machine we use doesn't produce stable results unfortunately. The ones on INTEL are much more stable. I could add more iterations automatically for ARM but I'd rather just wait for the new machines.

Yeah if I run it multiple times I see almost 6.8M RPS locally (with a fix for faster comparison against zero vector) while the best official result is ~6.4M

@halter73
Copy link
Member

@davidfowl Assuming we get a consistent >2% improvement in the modified plaintext benchmark (using Chrome request headers), would we be willing to take the unsafe code? I would be personally.

If we take it (no promises yet), we'll need to make sure we don't break on big-endian architectures. We should also reject the same requests we did before (e.g. "MyHeader:\r\n" should continue to fail even though "MyHeader: \r\n" doesn't). Don't feel compelled to do this before getting solid confirmation we're willing to take new unsafe code.

@mkArtakMSFT
Copy link
Member

Ping

@davidfowl, this seems to be blocked on your input.

@EgorBo EgorBo closed this Sep 21, 2022
@amcasey amcasey added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Jun 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants