diff options
author | Koundinya Veluri <kouvel@users.noreply.github.com> | 2019-04-03 06:51:43 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-03 06:51:43 -0700 |
commit | b4390c41f29af20e4cb77d296940bb6c4649ee86 (patch) | |
tree | 79939a83a5e20e3938eea5d53f84ea12865e56ee | |
parent | 5144947b45832e170b2eb3b8f909ec49d7122eaa (diff) | |
download | coreclr-b4390c41f29af20e4cb77d296940bb6c4649ee86.tar.gz coreclr-b4390c41f29af20e4cb77d296940bb6c4649ee86.tar.bz2 coreclr-b4390c41f29af20e4cb77d296940bb6c4649ee86.zip |
[Preview 4] Disable tier 0 JIT (quick JIT) by default, rename config option (#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
-rw-r--r-- | src/inc/clrconfigvalues.h | 12 | ||||
-rw-r--r-- | src/vm/callcounter.cpp | 4 | ||||
-rw-r--r-- | src/vm/eeconfig.cpp | 45 | ||||
-rw-r--r-- | src/vm/eeconfig.h | 22 | ||||
-rw-r--r-- | src/vm/method.cpp | 4 | ||||
-rw-r--r-- | src/vm/prestub.cpp | 2 | ||||
-rw-r--r-- | src/vm/tieredcompilation.cpp | 14 |
7 files changed, 54 insertions, 49 deletions
diff --git a/src/inc/clrconfigvalues.h b/src/inc/clrconfigvalues.h index 86a6166d1a..ef55ddef23 100644 --- a/src/inc/clrconfigvalues.h +++ b/src/inc/clrconfigvalues.h @@ -650,13 +650,13 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_GainExponent, /// #ifdef FEATURE_TIERED_COMPILATION RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TieredCompilation, W("TieredCompilation"), 1, "Enables tiered compilation") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TieredCompilation_Tier1CallCountThreshold, W("TieredCompilation_Tier1CallCountThreshold"), 30, "Number of times a method must be called after which it is promoted to tier 1.") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TieredCompilation_Tier1CallCountingDelayMs, W("TieredCompilation_Tier1CallCountingDelayMs"), 100, "A perpetual delay in milliseconds that is applied to tier 1 call counting and jitting, while there is tier 0 activity.") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TieredCompilation_Tier1DelaySingleProcMultiplier, W("TieredCompilation_Tier1DelaySingleProcMultiplier"), 10, "Multiplier for TieredCompilation_Tier1CallCountingDelayMs that is applied on a single-processor machine or when the process is affinitized to a single processor.") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TieredCompilation_DisableTier0Jit, W("TieredCompilation_DisableTier0Jit"), 0, "For methods that don't have pregenerated code, disable jitting them at tier 0 and start with a higher tier instead. For methods that have pregenerated code, tiering occurs normally.") +RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_QuickJit, W("TC_QuickJit"), 0, "For methods that would be jitted, enable using quick JIT when appropriate.") +RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_StartupTier_CallCountThreshold, W("TC_StartupTier_CallCountThreshold"), 30, "Number of times a method must be called in the startup tier after which it is promoted to the next tier.") +RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_StartupTier_CallCountingDelayMs, W("TC_StartupTier_CallCountingDelayMs"), 100, "A perpetual delay in milliseconds that is applied call counting in the startup tier and jitting at higher tiers, while there is startup-like activity.") +RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_StartupTier_DelaySingleProcMultiplier, W("TC_StartupTier_DelaySingleProcMultiplier"), 10, "Multiplier for TC_StartupTier_CallCountingDelayMs that is applied on a single-processor machine or when the process is affinitized to a single processor.") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TieredCompilation_Test_CallCounting, W("TieredCompilation_Test_CallCounting"), 1, "Enabled by default (only activates when TieredCompilation is also enabled). If disabled immediately backpatches prestub, and likely prevents any tier1 promotion") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TieredCompilation_Test_OptimizeTier0, W("TieredCompilation_Test_OptimizeTier0"), 0, "Use optimized codegen (normally used by tier1) in tier0") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_StartupTier_CallCounting, W("TC_StartupTier_CallCounting"), 1, "Enabled by default (only activates when TieredCompilation is also enabled). If disabled immediately backpatches prestub, and likely prevents any promotion to higher tiers") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_StartupTier_OptimizeCode, W("TC_StartupTier_OptimizeCode"), 0, "Use optimized codegen (normally used by the optimized tier) in the startup tier") #endif /// diff --git a/src/vm/callcounter.cpp b/src/vm/callcounter.cpp index ddf57f8d9d..4130345da0 100644 --- a/src/vm/callcounter.cpp +++ b/src/vm/callcounter.cpp @@ -39,7 +39,7 @@ bool CallCounter::IsEligibleForTier0CallCounting(MethodDesc* pMethodDesc) _ASSERTE(pMethodDesc != NULL); _ASSERTE(pMethodDesc->IsEligibleForTieredCompilation()); - return g_pConfig->TieredCompilation_CallCounting() && !pMethodDesc->RequestedAggressiveOptimization(); + return g_pConfig->TieredCompilation_StartupTier_CallCounting() && !pMethodDesc->RequestedAggressiveOptimization(); } bool CallCounter::IsTier0CallCountingEnabled(MethodDesc* pMethodDesc) @@ -131,7 +131,7 @@ void CallCounter::OnMethodCalled( if (pEntry == NULL) { isFirstTier0Call = true; - tier0CallCountLimit = (int)g_pConfig->TieredCompilation_Tier1CallCountThreshold() - 1; + tier0CallCountLimit = (int)g_pConfig->TieredCompilation_StartupTier_CallCountThreshold() - 1; _ASSERTE(tier0CallCountLimit >= 0); m_methodToCallCount.Add(CallCounterEntry(pMethodDesc, tier0CallCountLimit)); } diff --git a/src/vm/eeconfig.cpp b/src/vm/eeconfig.cpp index b5da7def9b..e59a85e1e5 100644 --- a/src/vm/eeconfig.cpp +++ b/src/vm/eeconfig.cpp @@ -348,11 +348,11 @@ HRESULT EEConfig::Init() #if defined(FEATURE_TIERED_COMPILATION) fTieredCompilation = false; - fTieredCompilation_DisableTier0Jit = false; - fTieredCompilation_CallCounting = false; - fTieredCompilation_OptimizeTier0 = false; - tieredCompilation_tier1CallCountThreshold = 1; - tieredCompilation_tier1CallCountingDelayMs = 0; + fTieredCompilation_QuickJit = false; + fTieredCompilation_StartupTier_CallCounting = false; + fTieredCompilation_StartupTier_OptimizeCode = false; + tieredCompilation_StartupTier_CallCountThreshold = 1; + tieredCompilation_StartupTier_CallCountingDelayMs = 0; #endif #ifndef CROSSGEN_COMPILE @@ -1204,37 +1204,38 @@ HRESULT EEConfig::sync() #if defined(FEATURE_TIERED_COMPILATION) fTieredCompilation = Configuration::GetKnobBooleanValue(W("System.Runtime.TieredCompilation"), CLRConfig::EXTERNAL_TieredCompilation) != 0; - fTieredCompilation_DisableTier0Jit = + + fTieredCompilation_QuickJit = Configuration::GetKnobBooleanValue( - W("System.Runtime.TieredCompilation.DisableTier0Jit"), - CLRConfig::UNSUPPORTED_TieredCompilation_DisableTier0Jit) != 0; + W("System.Runtime.TieredCompilation.QuickJit"), + CLRConfig::UNSUPPORTED_TC_QuickJit) != 0; - fTieredCompilation_CallCounting = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation_Test_CallCounting) != 0; - fTieredCompilation_OptimizeTier0 = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation_Test_OptimizeTier0) != 0; + fTieredCompilation_StartupTier_CallCounting = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_StartupTier_CallCounting) != 0; + fTieredCompilation_StartupTier_OptimizeCode = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_StartupTier_OptimizeCode) != 0; - tieredCompilation_tier1CallCountThreshold = - CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation_Tier1CallCountThreshold); - if (tieredCompilation_tier1CallCountThreshold < 1) + tieredCompilation_StartupTier_CallCountThreshold = + CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TC_StartupTier_CallCountThreshold); + if (tieredCompilation_StartupTier_CallCountThreshold < 1) { - tieredCompilation_tier1CallCountThreshold = 1; + tieredCompilation_StartupTier_CallCountThreshold = 1; } - else if (tieredCompilation_tier1CallCountThreshold > INT_MAX) // CallCounter uses 'int' + else if (tieredCompilation_StartupTier_CallCountThreshold > INT_MAX) // CallCounter uses 'int' { - tieredCompilation_tier1CallCountThreshold = INT_MAX; + tieredCompilation_StartupTier_CallCountThreshold = INT_MAX; } - tieredCompilation_tier1CallCountingDelayMs = - CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation_Tier1CallCountingDelayMs); + tieredCompilation_StartupTier_CallCountingDelayMs = + CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TC_StartupTier_CallCountingDelayMs); if (CPUGroupInfo::HadSingleProcessorAtStartup()) { DWORD delayMultiplier = - CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation_Tier1DelaySingleProcMultiplier); + CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TC_StartupTier_DelaySingleProcMultiplier); if (delayMultiplier > 1) { - DWORD newDelay = tieredCompilation_tier1CallCountingDelayMs * delayMultiplier; - if (newDelay / delayMultiplier == tieredCompilation_tier1CallCountingDelayMs) + DWORD newDelay = tieredCompilation_StartupTier_CallCountingDelayMs * delayMultiplier; + if (newDelay / delayMultiplier == tieredCompilation_StartupTier_CallCountingDelayMs) { - tieredCompilation_tier1CallCountingDelayMs = newDelay; + tieredCompilation_StartupTier_CallCountingDelayMs = newDelay; } } } diff --git a/src/vm/eeconfig.h b/src/vm/eeconfig.h index dc6725fb44..3a22adc74a 100644 --- a/src/vm/eeconfig.h +++ b/src/vm/eeconfig.h @@ -281,12 +281,12 @@ public: // Tiered Compilation config #if defined(FEATURE_TIERED_COMPILATION) - bool TieredCompilation(void) const {LIMITED_METHOD_CONTRACT; return fTieredCompilation; } - bool TieredCompilation_DisableTier0Jit() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_DisableTier0Jit; } - bool TieredCompilation_CallCounting() const {LIMITED_METHOD_CONTRACT; return fTieredCompilation_CallCounting; } - bool TieredCompilation_OptimizeTier0() const {LIMITED_METHOD_CONTRACT; return fTieredCompilation_OptimizeTier0; } - DWORD TieredCompilation_Tier1CallCountThreshold() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_tier1CallCountThreshold; } - DWORD TieredCompilation_Tier1CallCountingDelayMs() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_tier1CallCountingDelayMs; } + bool TieredCompilation(void) const { LIMITED_METHOD_CONTRACT; return fTieredCompilation; } + bool TieredCompilation_QuickJit() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_QuickJit; } + bool TieredCompilation_StartupTier_CallCounting() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_StartupTier_CallCounting; } + bool TieredCompilation_StartupTier_OptimizeCode() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_StartupTier_OptimizeCode; } + DWORD TieredCompilation_StartupTier_CallCountThreshold() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_StartupTier_CallCountThreshold; } + DWORD TieredCompilation_StartupTier_CallCountingDelayMs() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_StartupTier_CallCountingDelayMs; } #endif #ifndef CROSSGEN_COMPILE @@ -1013,11 +1013,11 @@ private: //---------------------------------------------------------------- #if defined(FEATURE_TIERED_COMPILATION) bool fTieredCompilation; - bool fTieredCompilation_DisableTier0Jit; - bool fTieredCompilation_CallCounting; - bool fTieredCompilation_OptimizeTier0; - DWORD tieredCompilation_tier1CallCountThreshold; - DWORD tieredCompilation_tier1CallCountingDelayMs; + bool fTieredCompilation_QuickJit; + bool fTieredCompilation_StartupTier_CallCounting; + bool fTieredCompilation_StartupTier_OptimizeCode; + DWORD tieredCompilation_StartupTier_CallCountThreshold; + DWORD tieredCompilation_StartupTier_CallCountingDelayMs; #endif #ifndef CROSSGEN_COMPILE diff --git a/src/vm/method.cpp b/src/vm/method.cpp index d180014a3a..2f6a9b4997 100644 --- a/src/vm/method.cpp +++ b/src/vm/method.cpp @@ -4803,6 +4803,10 @@ bool MethodDesc::DetermineAndSetIsEligibleForTieredCompilation() // Functional requirement CodeVersionManager::IsMethodSupported(this) && + // Policy - If quick JIT is disabled for the startup tier and the module is not ReadyToRun, the method would effectively + // not be tiered currently, so make the method ineligible for tiering to avoid some unnecessary overhead + (g_pConfig->TieredCompilation_QuickJit() || GetModule()->IsReadyToRun()) && + // Policy - Debugging works much better with unoptimized code !CORDisableJITOptimizations(GetModule()->GetDebuggerInfoBits()) && diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp index 975f86e193..c63e399332 100644 --- a/src/vm/prestub.cpp +++ b/src/vm/prestub.cpp @@ -373,7 +373,7 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig) if (pCode == NULL) { #ifdef FEATURE_TIERED_COMPILATION - if (g_pConfig->TieredCompilation_DisableTier0Jit() && + if (!g_pConfig->TieredCompilation_QuickJit() && IsEligibleForTieredCompilation() && pConfig->GetCodeVersion().GetOptimizationTier() == NativeCodeVersion::OptimizationTier0 && CallCounter::IsEligibleForTier0CallCounting(this)) diff --git a/src/vm/tieredcompilation.cpp b/src/vm/tieredcompilation.cpp index f091d0348d..1525d193b0 100644 --- a/src/vm/tieredcompilation.cpp +++ b/src/vm/tieredcompilation.cpp @@ -110,7 +110,7 @@ NativeCodeVersion::OptimizationTier TieredCompilationManager::GetInitialOptimiza return NativeCodeVersion::OptimizationTier1; } - if (!g_pConfig->TieredCompilation_CallCounting()) + if (!g_pConfig->TieredCompilation_StartupTier_CallCounting()) { // Call counting is disabled altogether through config, the intention is to remain at the initial tier return NativeCodeVersion::OptimizationTier0; @@ -151,7 +151,7 @@ void TieredCompilationManager::OnTier0MethodCalled( // Stop call counting when the delay is in effect IsTieringDelayActive() || // Initiate the delay on tier 0 activity (when a new eligible method is called the first time) - (isFirstCall && g_pConfig->TieredCompilation_Tier1CallCountingDelayMs() != 0) || + (isFirstCall && g_pConfig->TieredCompilation_StartupTier_CallCountingDelayMs() != 0) || // Stop call counting when ready for tier 1 promotion currentCallCountLimit <= 0; @@ -169,7 +169,7 @@ void TieredCompilationManager::OnMethodCallCountingStoppedWithoutTierPromotion(M _ASSERTE(pMethodDesc != nullptr); _ASSERTE(pMethodDesc->IsEligibleForTieredCompilation()); - if (g_pConfig->TieredCompilation_Tier1CallCountingDelayMs() == 0 || + if (g_pConfig->TieredCompilation_StartupTier_CallCountingDelayMs() == 0 || !pMethodDesc->GetCallCounter()->IsCallCountingEnabled(pMethodDesc)) { return; @@ -315,7 +315,7 @@ bool TieredCompilationManager::TryInitiateTieringDelay() { WRAPPER_NO_CONTRACT; _ASSERTE(g_pConfig->TieredCompilation()); - _ASSERTE(g_pConfig->TieredCompilation_Tier1CallCountingDelayMs() != 0); + _ASSERTE(g_pConfig->TieredCompilation_StartupTier_CallCountingDelayMs() != 0); NewHolder<SArray<MethodDesc*>> methodsPendingCountingHolder = new(nothrow) SArray<MethodDesc*>(); if (methodsPendingCountingHolder == nullptr) @@ -366,7 +366,7 @@ bool TieredCompilationManager::TryInitiateTieringDelay() &m_tieringDelayTimerHandle, TieringDelayTimerCallback, timerContextHolder, - g_pConfig->TieredCompilation_Tier1CallCountingDelayMs(), + g_pConfig->TieredCompilation_StartupTier_CallCountingDelayMs(), (DWORD)-1 /* Period, non-repeating */, 0 /* flags */)) { @@ -451,7 +451,7 @@ void TieredCompilationManager::TieringDelayTimerCallbackWorker() { if (ThreadpoolMgr::ChangeTimerQueueTimer( tieringDelayTimerHandle, - g_pConfig->TieredCompilation_Tier1CallCountingDelayMs(), + g_pConfig->TieredCompilation_StartupTier_CallCountingDelayMs(), (DWORD)-1 /* Period, non-repeating */)) { success = true; @@ -827,7 +827,7 @@ CORJIT_FLAGS TieredCompilationManager::GetJitFlags(NativeCodeVersion nativeCodeV } if (nativeCodeVersion.GetOptimizationTier() == NativeCodeVersion::OptimizationTier0 && - !g_pConfig->TieredCompilation_OptimizeTier0()) + !g_pConfig->TieredCompilation_StartupTier_OptimizeCode()) { flags.Set(CORJIT_FLAGS::CORJIT_FLAG_TIER0); } |