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

[Perf -30%] System.Tests.Perf_String.IndexerCheckPathLength #2290

Open
performanceautofiler bot opened this issue Oct 13, 2020 · 4 comments
Open

[Perf -30%] System.Tests.Perf_String.IndexerCheckPathLength #2290

performanceautofiler bot opened this issue Oct 13, 2020 · 4 comments

Comments

@performanceautofiler
Copy link

performanceautofiler bot commented Oct 13, 2020

Run Information

Architecture x64
OS ubuntu 18.04
Changes diff

Regressions in System.Tests.Perf_String

Benchmark Baseline Test Test/Base Modality Baseline Outlier Baseline ETL Comapre ETL
ToLowerInvariant 204.18 ns 3.78 ns 0.02 False
TrimEnd_CharArr 169.01 ns 4.42 ns 0.03 True
Replace_Char 148.17 ns 5.04 ns 0.03 Bimodal True
TrimEnd 154.22 ns 3.10 ns 0.02 Bimodal True
ToUpperInvariant 213.08 ns 3.95 ns 0.02 True
Trim 572.62 ns 13.34 ns 0.02 False
Replace_Char 450.05 ns 10.09 ns 0.02 Bimodal False
ToLower 285.16 ns 10.00 ns 0.04 False
Substring_Int 60.21 ns 1.31 ns 0.02 Bimodal True
Remove_Int 56.25 ns 1.58 ns 0.03 Bimodal False
TrimStart 147.71 ns 3.10 ns 0.02 Bimodal True

Related Issue on x86 Windows

[Perf -8%] System.Tests.Perf_String.Replace_Char

graph
graph
graph
graph
graph
graph
graph
graph
graph
graph
graph
Historical Data in Reporting System

Repro

git clone https://github.com/dotnet/performance.git
python3 .\performance\scripts\benchmarks_ci.py -f netcoreapp5.0 --filter 'System.Tests.Perf_String*'

Histogram

System.Tests.Perf_String.ToLowerInvariant(s: "test")

[3.733 ; 3.839) | @@@@@
[3.839 ; 3.930) | 
[3.930 ; 4.047) | @@@@@@@@@
[4.047 ; 4.153) | @@@@@@@@@@@@@@@@@@@@
[4.153 ; 4.252) | @@@
[4.252 ; 4.365) | @@@@@@@@@@@@@@@@@@@@@@@@@@@
[4.365 ; 4.471) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[4.471 ; 4.585) | @@@@@@@@@@@@@@@@@

System.Tests.Perf_String.TrimEnd_CharArr(s: "Test", c: [' ', ' '])

[4.255 ; 4.376) | @@
[4.376 ; 4.477) | @@@@@
[4.477 ; 4.640) | @@@
[4.640 ; 4.741) | @@@@@@@@@@@@@@@@@
[4.741 ; 4.900) | @@@@@@@@@@@@@@@@@@@@@@@
[4.900 ; 5.032) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[5.032 ; 5.174) | @@@@@@@@@@@@@@@@@@@@@@@@@

System.Tests.Perf_String.Replace_Char(text: "Hello", oldChar: 'a', newChar: 'b')

[4.523 ; 4.720) | @@
[4.720 ; 4.980) | @@@@@@@@@@@@@@@@@@@@@@@
[4.980 ; 5.185) | @@@@@@@@@@@@
[5.185 ; 5.448) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[5.448 ; 5.618) | @@@@@@@@@@
[5.618 ; 5.816) | @@@@@@@@@@@@@@@@@@@@@@@@@@@
[5.816 ; 5.936) | @@
[5.936 ; 6.059) | 
[6.059 ; 6.257) | @@@@@@@

System.Tests.Perf_String.TrimEnd(s: "Test")

[2.571 ; 2.729) | @@@@
[2.729 ; 2.861) | @
[2.861 ; 2.995) | @@@@@@@
[2.995 ; 3.141) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[3.141 ; 3.266) | @@@@@@
[3.266 ; 3.416) | @@@@@@@@@@@@@@@@@
[3.416 ; 3.561) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[3.561 ; 3.652) | @@@@@@@
[3.652 ; 3.741) | 
[3.741 ; 3.886) | @@@@@
[3.886 ; 3.984) | @

System.Tests.Perf_String.ToUpperInvariant(s: "TEST")

[3.785 ; 3.880) | @@@@
[3.880 ; 3.994) | @@@@
[3.994 ; 4.089) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[4.089 ; 4.188) | @@@@@@@@@@@@@@@
[4.188 ; 4.283) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[4.283 ; 4.416) | @@@@@@@@@@@@@@@
[4.416 ; 4.601) | @@@@@@@@@@@@@@@@

System.Tests.Perf_String.Trim(s: " Test")

[13.120 ; 13.547) | @@@@@@@@@@@@@
[13.547 ; 13.965) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[13.965 ; 14.387) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[14.387 ; 14.826) | @@@@@@@@@@@@@@@@@@@@

System.Tests.Perf_String.Replace_Char(text: "This is a very nice sentence", oldChar: 'z', newChar: 'y')

[ 8.037 ;  8.691) | @@@@@@@@@@
[ 8.691 ;  9.486) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[ 9.486 ; 10.001) | @@@@@@
[10.001 ; 10.627) | @@@@@@@@@
[10.627 ; 11.281) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[11.281 ; 11.948) | @@@@@@@@@@@@@@@@@@@
[11.948 ; 12.690) | @@@@@@@@@
[12.690 ; 13.095) | @

System.Tests.Perf_String.ToLower(s: "test")

[ 9.997 ; 10.487) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[10.487 ; 10.825) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[10.825 ; 11.215) | @@@@@@@
[11.215 ; 11.553) | @@@@
[11.553 ; 12.030) | @@
[12.030 ; 12.538) | @@@@@@
[12.538 ; 12.997) | @@
[12.997 ; 13.335) | 
[13.335 ; 13.679) | 
[13.679 ; 14.017) | @

System.Tests.Perf_String.Substring_Int(s: "dzsdzsDDZSDZSDZSddsz", i: 0)

[1.038 ; 1.268) | @@@@@@@@@@@@@@@
[1.268 ; 1.501) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[1.501 ; 1.598) | @@@@@@@@@
[1.598 ; 1.831) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[1.831 ; 1.950) | @
[1.950 ; 2.183) | 
[2.183 ; 2.416) | 
[2.416 ; 2.649) | 
[2.649 ; 2.882) | 
[2.882 ; 3.115) | 
[3.115 ; 3.348) | 
[3.348 ; 3.581) | 
[3.581 ; 3.814) | 
[3.814 ; 4.047) | 
[4.047 ; 4.280) | 
[4.280 ; 4.514) | 
[4.514 ; 4.747) | 
[4.747 ; 4.980) | 
[4.980 ; 5.213) | 
[5.213 ; 5.446) | 
[5.446 ; 5.538) | 
[5.538 ; 5.771) | @

System.Tests.Perf_String.Remove_Int(s: "dzsdzsDDZSDZSDZSddsz", i: 0)

[1.267 ; 1.492) | @@@@@@@
[1.492 ; 1.644) | @@@@@@@@@@@@@@@
[1.644 ; 1.910) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[1.910 ; 2.117) | @@@@@@@@@@@@@@
[2.117 ; 2.191) | 
[2.191 ; 2.398) | @@@@@@@@@@@@@@@@@@@
[2.398 ; 2.673) | @@@@@@@@@@@@@@@@@@@@@@@@@

System.Tests.Perf_String.TrimStart(s: "Test")

[2.533 ; 2.678) | @
[2.678 ; 2.842) | @@
[2.842 ; 3.012) | @@@@@@@@@@@@@@@@@@@@@@@@@
[3.012 ; 3.157) | @@@@@@@@@@@@@@@@@@@@@@@@@
[3.157 ; 3.231) | 
[3.231 ; 3.376) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
[3.376 ; 3.563) | @@@@@@@@@@@@@@@@@@@
[3.563 ; 3.722) | @@@@@@@@@@@
[3.722 ; 3.867) | @@@@

Docs

Profiling workflow for dotnet/runtime repository
Benchmarking workflow for dotnet/runtime repository

@kunalspathak
Copy link
Collaborator

@DrewScoggins - I see the title says IndexerCheckPathLength, but I don't see data of that benchmark in this issue. Any idea why?

@DrewScoggins
Copy link
Owner

Hmm, I am not sure, but it looks like this did not get filed correctly. I will take a look at this.

@kunalspathak
Copy link
Collaborator

The benchmark shows regression after my 32B method alignment changes because the hot loop earlier was contained in a 32B chunk, but with alignment, is split. However, I don't see the loop alignment changes would have any effect on this benchmark because there is a method call inside the loop that would just flush the cached code from DSB that that of the method Perf_String:getStringCharNoInline code.

Before loop alignment:

G_M42081_IG03:              ;; offset=0034H
 00007ffb`a6f66c94        488BCE               mov      rcx, rsi
 00007ffb`a6f66c97        8BD3                 mov      edx, ebx
 00007ffb`a6f66c99        E83A1A90FF           call     System.Tests.Perf_String:getStringCharNoInline(System.String,int):ushort
 00007ffb`a6f66c9e        03F8                 add      edi, eax
; =========================== 32B boundary ===========================
 00007ffb`a6f66ca0        FFC3                 inc      ebx
 00007ffb`a6f66ca2        3BEB                 cmp      ebp, ebx
 00007ffb`a6f66ca4        7FEE                 jg       SHORT G_M42081_IG03
                                                ;; bbWeight=4    PerfScore 13.00

After loop alignment:

 00007ffb`a6f371b4        0F1F40000F1F840000000000 align
; =========================== 32B boundary ===========================
 00007ffb`a6f371c0                             align
 00007ffb`a6f371c0                             align
                                                ;; bbWeight=1    PerfScore 8.25
G_M42081_IG03:              ;; offset=0040H
 00007ffb`a6f371c0        488BCE               mov      rcx, rsi
 00007ffb`a6f371c3        8BD3                 mov      edx, ebx
 00007ffb`a6f371c5        E88E1690FF           call     System.Tests.Perf_String:getStringCharNoInline(System.String,int):ushort
 00007ffb`a6f371ca        03F8                 add      edi, eax
 00007ffb`a6f371cc        FFC3                 inc      ebx
 00007ffb`a6f371ce        3BEB                 cmp      ebp, ebx
 00007ffb`a6f371d0        7FEE                 jg       SHORT G_M42081_IG03

@kunalspathak
Copy link
Collaborator

This was brought up in the past in dotnet/runtime#13090 (comment). From my analysis and trying out the loop alignment changes, this benchmark could certainly showing bimodal behavior because of memory alignment of string _s1 ?

DrewScoggins pushed a commit that referenced this issue Mar 31, 2022
* Update dependencies from https://github.com/dotnet/arcade build 20220303.1

Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk
 From Version 7.0.0-beta.22152.1 -> To Version 7.0.0-beta.22153.1

* Update dependencies from https://github.com/dotnet/arcade build 20220304.3

Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk
 From Version 7.0.0-beta.22152.1 -> To Version 7.0.0-beta.22154.3

* Update dependencies from https://github.com/dotnet/arcade build 20220307.6

Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk
 From Version 7.0.0-beta.22152.1 -> To Version 7.0.0-beta.22157.6

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
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

2 participants