Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

[Preview 4] Disable tier 0 JIT (quick JIT) by default, rename config option #23599

Merged
merged 3 commits into from
Apr 3, 2019

Conversation

kouvel
Copy link
Member

@kouvel kouvel commented Mar 30, 2019

  • Tier 0 JIT is being called quick JIT in config options, renamed DisableTier0Jit to StartupTierQuickJit
  • Disabled quick JIT by default, the current plan is to do that for preview 4
    • Concerns were that code produced by quick JIT may be slow, may allocate more, may use more stack space, and may be much larger than optimized code, and there there may be many cases where these things lead to regressions when the span of time between startup and steady-state is important
    • The thought was that with quick JIT disabled, tiering overhead from call counting and backgorund jitting with optimizations would be less, and perf during any point in time would be closer to 2.x releases
    • This mostly loses the startup perf gains from tiering. It may also be slightly slower compared with tiering off due to some overhead. When quick JIT is disabled for the startup tier, made a change to disable tiered compilation for methods in modules that are not R2R'ed since they will not be tiered currently anyway. The overhead and regression in R2R'ed modules will be looked into separately to see if it can be reduced.
  • Added config option ForceQuickJit, which uses quick JIT instead of the normal JIT. Off by default. Disables tiering.

The environment variable is COMPlus_TC_QuickJit, it's 0 by default and may be set to 1 to enable.

Fixes https://github.com/dotnet/coreclr/issues/22998
Fixes https://github.com/dotnet/coreclr/issues/19751

@kouvel kouvel added this to the 3.0 milestone Mar 30, 2019
@kouvel kouvel self-assigned this Mar 30, 2019
@kouvel
Copy link
Member Author

kouvel commented Mar 30, 2019

CC @jkotas @richlander

kouvel added a commit to kouvel/coreclr that referenced this pull request Mar 30, 2019
Depends on dotnet#23599

- Renamed tier 0 / tier 1 to StartupTier, OptimizedTier
- Added config option QuickJitForLoops, which determines whether quick JIT, when enabled, may be used for methods that contain loops. Off by default, so after this change, StartupTierQuickJit=1 or ForceQuickJit=1 would still not use quick JIT for methods that contain loops by default.
@benaadams
Copy link
Member

Disabled quick JIT by default

Is the plan to switch it back on by default at some point? As it does make steady state code better when it gets there over both initial Tier1 (due to things like readonly statics being pre-evaluated in an earlier Jit phase) and R2R, as runtime Jit has more info than crossgen Jit.

@kouvel
Copy link
Member Author

kouvel commented Mar 30, 2019

Tiering up from R2R code to optimized jitted code is still enabled. Methods that don't have R2R code would skip the quick JIT and go straight to the optimized one. As we get more information on what kind of issues may occur with the quick JIT code it may stabilize enough to enable again.

@kouvel
Copy link
Member Author

kouvel commented Mar 31, 2019

Perf results are here: #23597 (comment)

Except that with this change, Tier+QJ is equivalent in perf to the numbers in the Tier+QJ+QJL columns in the numbers above (QuickJit=1 enables quick-jitting methods that contain loops).

@kouvel
Copy link
Member Author

kouvel commented Mar 31, 2019

@dotnet-bot test Ubuntu x64 Checked CoreFX Tests

@AndyAyersMS
Copy link
Member

What is the intended purpose of ForceQuickJit?

Showing perf impact as percentage change from some other configuration as in #23597 seems odd. Would like to see the results impacted by this change compared directly instead. Say a table here with just (old default) vs (new default).

src/vm/jitinterface.cpp Outdated Show resolved Hide resolved
@kouvel
Copy link
Member Author

kouvel commented Apr 1, 2019

Posted new tables comparing after vs before directly, and after vs no-tier here: #23597 (comment)

The purpose of ForceQuickJit is to be able to test with the quick JIT as opposed to min-opt JIT, which may diverge more from min-opt JIT in the future, to see what kind of startup perf improvement could be had in some cases and also as a goal for startup perf when tiering is enabled.

@kouvel
Copy link
Member Author

kouvel commented Apr 1, 2019

Posting perf numbers here as well. Lower is better for all diffs.


JitBench startup perf - time (ms)

  NoTier Before After Diff from before Diff from NoTier
DotNetBuildHelloWorld 1332.14 1290.33 1387.14 7.50% 4.13%
CscHelloWorld 609.00 500.00 632.57 26.51% 3.87%
CscRoslynSource 2316.29 2353.80 2461.33 4.57% 6.26%
EmptyConsoleProgram 57.86 56.67 57.57 1.60% -0.49%
MusicStoreStartup 597.57 551.71 615.60 11.58% 3.02%
MusicStoreFirstRequest 513.29 406.00 534.20 31.58% 4.07%

ASP.NET startup perf - time (ms), server start + first request

  NoTier Before After Diff from before Diff from NoTier
DbFortunesEf Windows 1783.16 1282.57 1833.70 42.97% 2.83%
DbFortunesEf Linux 1774.85 1253.31 1823.57 45.50% 2.75%
DbFortunesRaw Windows 1064.10 839.72 1074.16 27.92% 0.95%
DbFortunesRaw Linux 1100.03 828.14 1102.17 33.09% 0.19%
Json Windows 565.31 516.31 586.11 13.52% 3.68%
Json Linux 518.77 417.72 525.45 25.79% 1.29%
MvcJson Windows 735.69 654.59 758.05 15.81% 3.04%
MvcJson Linux 671.86 547.66 691.51 26.27% 2.92%
MvcPlaintext Windows 656.82 581.36 666.21 14.60% 1.43%
MvcPlaintext Linux 611.49 506.87 627.18 23.74% 2.57%
Plaintext Windows 487.44 421.02 501.95 19.22% 2.98%
Plaintext Linux 427.12 348.57 435.44 24.92% 1.95%

JitBench startup perf - R2R disabled

  NoTier Before After Diff from before Diff from NoTier
DotNetBuildHelloWorld 3547.86 2568.17 3573.43 39.14% 0.72%
CscHelloWorld 2194.86 1212.17 2194.57 81.05% -0.01%
CscRoslynSource 4001.14 3645.57 3998.43 9.68% -0.07%
EmptyConsoleProgram 101.57 84.57 102.14 20.78% 0.56%
MusicStoreStartup 2071.57 1268.33 2067.71 63.03% -0.19%
MusicStoreFirstRequest 1738.29 977.14 1730.71 77.12% -0.44%

ASP.NET startup perf - R2R disabled - time (ms), server start + first request

  NoTier Before After Diff from before Diff from NoTier
DbFortunesEf Windows 2827.39 1808.65 2811.59 55.45% -0.56%
DbFortunesEf Linux 2694.68 1763.44 2734.69 55.08% 1.48%
DbFortunesRaw Windows 1971.53 1282.32 1955.90 52.53% -0.79%
DbFortunesRaw Linux 1914.01 1259.21 1886.68 49.83% -1.43%
Json Windows 1309.95 865.64 1297.10 49.84% -0.98%
Json Linux 1194.95 797.74 1199.75 50.39% 0.40%
MvcJson Windows 1878.55 1240.70 1885.21 51.95% 0.35%
MvcJson Linux 1740.76 1149.11 1745.34 51.89% 0.26%
MvcPlaintext Windows 1676.32 1077.02 1669.72 55.03% -0.39%
MvcPlaintext Linux 1567.92 1031.59 1565.73 51.78% -0.14%
Plaintext Windows 1100.61 739.77 1102.61 49.05% 0.18%
Plaintext Linux 1017.82 683.04 1020.50 49.41% 0.26%

JitBench steady-state perf - time (ms)

  NoTier Before After Diff from before Diff from NoTier
MusicStoreMedianResponse 2.58 1.87 1.82 -2.37% -29.44%
Word2VecTraining 32511.14 32503.14 32676.43 0.53% 0.51%
Word2VecMedianSearch 21.47 21.59 21.63 0.21% 0.76%

ASP.NET steady-state perf - time (ns) per request

  NoTier NoTier,NoR2r Before After Diff from before Diff from NoTier Diff from NoTier,NoR2r
DbFortunesEf Linux 14965.92 12743.28 12650.50 12865.87 1.70% -14.03% 0.96%
DbFortunesRaw Linux 10653.14 8670.81 8693.86 8793.95 1.15% -17.45% 1.42%
Json Linux 3600.04 2662.96 2639.31 2619.86 -0.74% -27.23% -1.62%
Json https Linux 5788.02 4394.60 4340.89 4338.63 -0.05% -25.04% -1.27%
MvcJson Linux 8867.86 5927.52 5788.18 5843.80 0.96% -34.10% -1.41%
MvcPlaintext Linux 3071.05 1677.61 1636.26 1630.24 -0.37% -46.92% -2.82%
Plaintext Linux 756.31 509.73 504.92 499.42 -1.09% -33.97% -2.02%
Plaintext https Linux 1607.07 1119.20 1092.08 1112.21 1.84% -30.79% -0.62%
PlaintextNonPipelined Linux 2804.53 2101.86 2089.88 2093.27 0.16% -25.36% -0.41%
PlaintextNonPipelined https Linux 4922.10 3943.04 3916.68 3960.39 1.12% -19.54% 0.44%

src/inc/clrconfigvalues.h Outdated Show resolved Hide resolved
Copy link
Member

@AndyAyersMS AndyAyersMS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For methods in R2R modules that were not prejitted, will we end up jitting them twice?

kouvel added a commit to kouvel/coreclr that referenced this pull request Apr 1, 2019
Depends on dotnet#23599

- Renamed tier 0 / tier 1 to StartupTier, OptimizedTier
- Added config option QuickJitForLoops, which determines whether quick JIT, when enabled, may be used for methods that contain loops. Off by default, so after this change, StartupTierQuickJit=1 or ForceQuickJit=1 would still not use quick JIT for methods that contain loops by default.
@kouvel
Copy link
Member Author

kouvel commented Apr 1, 2019

For methods in R2R modules that were not prejitted, will we end up jitting them twice?

No they will only be jitted once at tier 1. Those methods reach this path:
https://github.com/kouvel/coreclr/blob/9d7a242ed57e45055a7f752615d17de80ad03a8f/src/vm/prestub.cpp#L381-L382

When call counting is disabled in the startup tier, it affects the initial optimization tier for the method:
https://github.com/kouvel/coreclr/blob/9d7a242ed57e45055a7f752615d17de80ad03a8f/src/vm/tieredcompilation.cpp#L119-L124

That is used for the default NativeCodeVersion here:
https://github.com/kouvel/coreclr/blob/9d7a242ed57e45055a7f752615d17de80ad03a8f/src/vm/codeversion.cpp#L343-L370

kouvel added a commit to kouvel/coreclr that referenced this pull request Apr 1, 2019
Depends on dotnet#23599

- Renamed tier 0 / tier 1 to StartupTier, OptimizedTier
- Added config option QuickJitForLoops, which determines whether quick JIT, when enabled, may be used for methods that contain loops. Off by default, so after this change, StartupTierQuickJit=1 or ForceQuickJit=1 would still not use quick JIT for methods that contain loops by default.
@noahfalk
Copy link
Member

noahfalk commented Apr 1, 2019

@kouvel - just so it isn't surprising later, I have mixed feelings about the current config names. I'm fine to discuss that in the context of final naming we use in 3.0 RTM and did not want to hold up your work here changing the Preview4 defaults.

@kouvel
Copy link
Member Author

kouvel commented Apr 1, 2019

Maybe we can have a quick chat about that soon. I'm not sure if anyone will be enabling the QuickJit flag, but since it appears to be worth it for several cases, I'd like to get the naming right sooner rather than later.

kouvel added a commit to kouvel/coreclr that referenced this pull request Apr 2, 2019
Depends on dotnet#23599

- Renamed tier 0 / tier 1 to StartupTier, OptimizedTier
- Added config option QuickJitForLoops, which determines whether quick JIT, when enabled, may be used for methods that contain loops. Off by default, so after this change, StartupTierQuickJit=1 or ForceQuickJit=1 would still not use quick JIT for methods that contain loops by default.
- Tier 0 JIT is being called quick JIT in config options, renamed DisableTier0Jit to StartupTierQuickJit
- Disabled quick JIT by default, the current plan is to do that for preview 4
  - Concerns were that code produced by quick JIT may be slow, may allocate more, may use more stack space, and may be much larger than optimized code, and there there may be many cases where these things lead to regressions when the span of time between startup and steady-state is important
  - The thought was that with quick JIT disabled, tiering overhead from call counting and backgorund jitting with optimizations would be less, and perf during any point in time would be closer to 2.x releases
  - This mostly loses the startup perf gains from tiering. It may also be slightly slower compared with tiering off due to some overhead. When quick JIT is disabled for the startup tier, made a change to disable tiered compilation for methods in modules that are not R2R'ed since they will not be tiered currently anyway. The overhead and regression in R2R'ed modules will be looked into separately to see if it can be reduced.
- Added config option ForceQuickJit, which uses quick JIT instead of the normal JIT. Off by default. Disables tiering.

Fixes https://github.com/dotnet/coreclr/issues/22998
Fixes https://github.com/dotnet/coreclr/issues/19751
kouvel added a commit to kouvel/coreclr that referenced this pull request Apr 2, 2019
Depends on dotnet#23599

- Renamed tier 0 / tier 1 to StartupTier, OptimizedTier
- Added config option QuickJitForLoops, which determines whether quick JIT, when enabled, may be used for methods that contain loops. Off by default, so after this change, StartupTierQuickJit=1 or ForceQuickJit=1 would still not use quick JIT for methods that contain loops by default.
@kouvel
Copy link
Member Author

kouvel commented Apr 3, 2019

In Ubuntu x64 Checked CoreFX Tests it seems to be running an old version of the ThrowExceptionForHR_ErrorInfo_ReturnsValidException test, the issue appears to have been fixed by dotnet/corefx#34968 a while back.

@kouvel kouvel merged commit b4390c4 into dotnet:master Apr 3, 2019
@kouvel kouvel deleted the QuickJitP4 branch April 3, 2019 13:51
@jkotas
Copy link
Member

jkotas commented Apr 3, 2019

Ubuntu x64 Checked CoreFX Tests it seems to be running an old version

The old snapshot is by design for the time being. PRs that hit issues with the old snapshot of CoreFX tests are expected to disable the offending tests in https://github.com/dotnet/coreclr/blob/master/tests/CoreFX/CoreFX.issues.json

Could you please submit PR to disable the offending test to make the CI on master green?

@kouvel
Copy link
Member Author

kouvel commented Apr 3, 2019

Oh ok, will do

@AndyAyersMS
Copy link
Member

@dotnet/jit-contrib we need to look at what this does to our CI test coverage.

We should make sure we have some runs where TC is enabled that also turn on "quick jit."

picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…option (dotnet/coreclr#23599)

Disable tier 0 JIT (quick JIT) by default, rename config option

- Tier 0 JIT is being called quick JIT in config options, renamed DisableTier0Jit to StartupTierQuickJit
- Disabled quick JIT by default, the current plan is to do that for preview 4
  - Concerns were that code produced by quick JIT may be slow, may allocate more, may use more stack space, and may be much larger than optimized code, and there there may be many cases where these things lead to regressions when the span of time between startup and steady-state is important
  - The thought was that with quick JIT disabled, tiering overhead from call counting and backgorund jitting with optimizations would be less, and perf during any point in time would be closer to 2.x releases
  - This mostly loses the startup perf gains from tiering. It may also be slightly slower compared with tiering off due to some overhead. When quick JIT is disabled for the startup tier, made a change to disable tiered compilation for methods in modules that are not R2R'ed since they will not be tiered currently anyway. The overhead and regression in R2R'ed modules will be looked into separately to see if it can be reduced.

Fixes https://github.com/dotnet/coreclr/issues/22998
Fixes https://github.com/dotnet/coreclr/issues/19751

Commit migrated from dotnet/coreclr@b4390c4
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
5 participants