[Preview 4] Disable tier 0 JIT (quick JIT) by default, rename config option (dotnet...
authorKoundinya Veluri <kouvel@users.noreply.github.com>
Wed, 3 Apr 2019 13:51:43 +0000 (06:51 -0700)
committerGitHub <noreply@github.com>
Wed, 3 Apr 2019 13:51:43 +0000 (06:51 -0700)
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 https://github.com/dotnet/coreclr/commit/b4390c41f29af20e4cb77d296940bb6c4649ee86

src/coreclr/src/inc/clrconfigvalues.h
src/coreclr/src/vm/callcounter.cpp
src/coreclr/src/vm/eeconfig.cpp
src/coreclr/src/vm/eeconfig.h
src/coreclr/src/vm/method.cpp
src/coreclr/src/vm/prestub.cpp
src/coreclr/src/vm/tieredcompilation.cpp

index 86a6166..ef55dde 100644 (file)
@@ -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
 
 ///
index ddf57f8..4130345 100644 (file)
@@ -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));
         }
index b5da7de..e59a85e 100644 (file)
@@ -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;
             }
         }
     }
index dc6725f..3a22adc 100644 (file)
@@ -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
index d180014..2f6a9b4 100644 (file)
@@ -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()) &&
 
index 975f86e..c63e399 100644 (file)
@@ -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))
index f091d03..1525d19 100644 (file)
@@ -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);
     }