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

Fix x86 steady state tiered compilation performance #17476

Merged
merged 2 commits into from Apr 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/inc/clrconfigvalues.h
Expand Up @@ -654,6 +654,9 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TieredCompilation, W("TieredCompilation"), 0,
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_LEGACY_TieredCompilation, W("EXPERIMENTAL_TieredCompilation"), 0, "Deprecated - Use COMPLUS_TieredCompilation")
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, "Delay in milliseconds since process startup or the last tier 0 JIT before call counting begins for tier 1 promotion.")

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")
#endif


Expand Down
5 changes: 5 additions & 0 deletions src/vm/eeconfig.cpp
Expand Up @@ -375,6 +375,8 @@ HRESULT EEConfig::Init()

#if defined(FEATURE_TIERED_COMPILATION)
fTieredCompilation = false;
fTieredCompilation_CallCounting = false;
fTieredCompilation_OptimizeTier0 = false;
tieredCompilation_tier1CallCountThreshold = 1;
tieredCompilation_tier1CallCountingDelayMs = 0;
#endif
Expand Down Expand Up @@ -1242,6 +1244,9 @@ HRESULT EEConfig::sync()
//this older name is deprecated, but still accepted for a time. Preserving it is a very small overhead not to needlessly break things.
CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_LEGACY_TieredCompilation) != 0;

fTieredCompilation_CallCounting = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation_Test_CallCounting) != 0;
fTieredCompilation_OptimizeTier0 = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation_Test_OptimizeTier0) != 0;

tieredCompilation_tier1CallCountThreshold =
CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation_Tier1CallCountThreshold);
if (tieredCompilation_tier1CallCountThreshold < 1)
Expand Down
4 changes: 4 additions & 0 deletions src/vm/eeconfig.h
Expand Up @@ -285,6 +285,8 @@ class EEConfig
// Tiered Compilation config
#if defined(FEATURE_TIERED_COMPILATION)
bool TieredCompilation(void) const {LIMITED_METHOD_CONTRACT; return fTieredCompilation; }
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; }
#endif
Expand Down Expand Up @@ -1109,6 +1111,8 @@ class EEConfig

#if defined(FEATURE_TIERED_COMPILATION)
bool fTieredCompilation;
bool fTieredCompilation_CallCounting;
bool fTieredCompilation_OptimizeTier0;
DWORD tieredCompilation_tier1CallCountThreshold;
DWORD tieredCompilation_tier1CallCountingDelayMs;
#endif
Expand Down
6 changes: 5 additions & 1 deletion src/vm/method.cpp
Expand Up @@ -2414,7 +2414,11 @@ BOOL MethodDesc::RequiresMethodDescCallingConvention(BOOL fEstimateForChunk /*=F
BOOL MethodDesc::RequiresStableEntryPoint(BOOL fEstimateForChunk /*=FALSE*/)
{
LIMITED_METHOD_CONTRACT;


// Create precodes for versionable methods
if (IsVersionableWithPrecode())
return TRUE;

// Create precodes for edit and continue to make methods updateable
if (IsEnCMethod() || IsEnCAddedMethod())
return TRUE;
Expand Down
2 changes: 1 addition & 1 deletion src/vm/method.hpp
Expand Up @@ -284,7 +284,7 @@ class MethodDesc
}
CONTRACTL_END

return !MayHaveNativeCode() || IsRemotingInterceptedViaPrestub();
return !MayHaveNativeCode() || IsRemotingInterceptedViaPrestub() || IsVersionableWithPrecode();
}

void InterlockedUpdateFlags2(BYTE bMask, BOOL fSet);
Expand Down
13 changes: 9 additions & 4 deletions src/vm/prestub.cpp
Expand Up @@ -1734,15 +1734,20 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
// When the TieredCompilationManager has received enough call notifications
// for this method only then do we back-patch it.
BOOL fCanBackpatchPrestub = TRUE;
BOOL fEligibleForCallCounting = FALSE;
#ifdef FEATURE_TIERED_COMPILATION
TieredCompilationManager* pTieredCompilationManager = nullptr;
BOOL fEligibleForTieredCompilation = IsEligibleForTieredCompilation();
BOOL fWasPromotedToTier1 = FALSE;
if (fEligibleForTieredCompilation)
{
pTieredCompilationManager = GetAppDomain()->GetTieredCompilationManager();
CallCounter * pCallCounter = GetCallCounter();
pCallCounter->OnMethodCalled(this, pTieredCompilationManager, &fCanBackpatchPrestub, &fWasPromotedToTier1);
fEligibleForCallCounting = g_pConfig->TieredCompilation_CallCounting();
if (fEligibleForCallCounting)
{
pTieredCompilationManager = GetAppDomain()->GetTieredCompilationManager();
CallCounter * pCallCounter = GetCallCounter();
pCallCounter->OnMethodCalled(this, pTieredCompilationManager, &fCanBackpatchPrestub, &fWasPromotedToTier1);
}
}
#endif

Expand All @@ -1755,7 +1760,7 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
{
pCode = GetCodeVersionManager()->PublishVersionableCodeIfNecessary(this, fCanBackpatchPrestub);

if (pTieredCompilationManager != nullptr && fCanBackpatchPrestub && pCode != NULL && !fWasPromotedToTier1)
if (pTieredCompilationManager != nullptr && fEligibleForCallCounting && fCanBackpatchPrestub && pCode != NULL && !fWasPromotedToTier1)
{
pTieredCompilationManager->OnMethodCallCountingStoppedWithoutTier1Promotion(this);
}
Expand Down
3 changes: 2 additions & 1 deletion src/vm/tieredcompilation.cpp
Expand Up @@ -611,7 +611,8 @@ CORJIT_FLAGS TieredCompilationManager::GetJitFlags(NativeCodeVersion nativeCodeV
return flags;
}

if (nativeCodeVersion.GetOptimizationTier() == NativeCodeVersion::OptimizationTier0)
if (nativeCodeVersion.GetOptimizationTier() == NativeCodeVersion::OptimizationTier0 &&
!g_pConfig->TieredCompilation_OptimizeTier0())
{
flags.Set(CORJIT_FLAGS::CORJIT_FLAG_TIER0);
}
Expand Down
10 changes: 4 additions & 6 deletions tests/src/performance/Scenario/JitBench/Runner/Benchmark.cs
Expand Up @@ -71,15 +71,13 @@ BenchmarkRunResult MeasureIterations(TestRun run, BenchmarkConfiguration config,
startInfo.WorkingDirectory = WorkingDirPath;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
foreach (KeyValuePair<string, string> kv in config.EnvironmentVariables)
IEnumerable<KeyValuePair<string, string>> extraEnvVars = config.EnvironmentVariables.Concat(EnvironmentVariables).Append(new KeyValuePair<string, string>("DOTNET_MULTILEVEL_LOOKUP", "0"));
foreach (KeyValuePair<string, string> kv in extraEnvVars)
{
startInfo.Environment[kv.Key] = kv.Value;
}
foreach (KeyValuePair<string, string> kv in EnvironmentVariables)
{
startInfo.Environment[kv.Key] = kv.Value;
}
startInfo.Environment["DOTNET_MULTILEVEL_LOOKUP"] = "0";
output.WriteLine("XUnitPerfHarness doesn't log env vars it uses to run processes. To workaround, logging them here:");
output.WriteLine(string.Join(", ", extraEnvVars.Select(kv => kv.Key + "=" + kv.Value)));

BenchmarkRunResult result = new BenchmarkRunResult(this, config);
StringBuilder stderr = new StringBuilder();
Expand Down