Skip to content

Commit

Permalink
JIT: profile synthesis blend and repair modes (#83567)
Browse files Browse the repository at this point in the history
Implement blend and repair modes for synthesis. Blend merges a bit of
synthesized data into an existing PGO data set; repair tries to fix any
local inconsistencies (via heuristics). Both run count construction
afterwards.

Trust blended data like we trust dynamic data. Probably will want more
nuance here (eg trust dynamic blend, but not static blend) but this is
sufficent for now.

Also implement random and reverse modes; these will ultimately be used
for stress testing (not called anywhere yet).

Parameterize some of the magic constants that have cropped up.

Add blend mode as a new weekend pgo stress mode; fix the other synthesis
mode I added recently to pgo stress to set the config properly.

Contributes to #82964.
  • Loading branch information
AndyAyersMS authored Mar 17, 2023
1 parent 8a786a7 commit bbc5634
Show file tree
Hide file tree
Showing 9 changed files with 424 additions and 32 deletions.
1 change: 1 addition & 0 deletions eng/pipelines/common/templates/runtimes/run-test-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ jobs:
- fullpgo_random_gdv_edge
- fullpgo_methodprofiling_always_optimized
- syntheticpgo
- syntheticpgo_blend
${{ if in(parameters.testGroup, 'gc-longrunning') }}:
longRunningGcTests: true
scenarios:
Expand Down
2 changes: 2 additions & 0 deletions eng/pipelines/libraries/run-test-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,5 @@ jobs:
- jitosr_stress
- jitosr_stress_random
- syntheticpgo
- syntheticpgo_blend

6 changes: 6 additions & 0 deletions src/coreclr/jit/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -1867,6 +1867,12 @@ struct FlowEdge
m_likelihood = likelihood;
}

void clearLikelihood()
{
m_likelihood = 0.0;
INDEBUG(m_likelihoodSet = false);
}

#ifdef DEBUG
bool hasLikelihood() const
{
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5561,7 +5561,7 @@ class Compiler

#endif // DEBUG

static bool fgProfileWeightsEqual(weight_t weight1, weight_t weight2);
static bool fgProfileWeightsEqual(weight_t weight1, weight_t weight2, weight_t epsilon = 0.01);
static bool fgProfileWeightsConsistent(weight_t weight1, weight_t weight2);

static GenTree* fgGetFirstNode(GenTree* tree);
Expand Down
18 changes: 15 additions & 3 deletions src/coreclr/jit/fgprofile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ bool Compiler::fgHaveSufficientProfileWeights()
{
case ICorJitInfo::PgoSource::Dynamic:
case ICorJitInfo::PgoSource::Text:
case ICorJitInfo::PgoSource::Blend:
return true;

case ICorJitInfo::PgoSource::Static:
case ICorJitInfo::PgoSource::Blend:
{
// We sometimes call this very early, eg evaluating the prejit root.
//
Expand Down Expand Up @@ -123,6 +123,7 @@ bool Compiler::fgHaveTrustedProfileWeights()
switch (fgPgoSource)
{
case ICorJitInfo::PgoSource::Dynamic:
case ICorJitInfo::PgoSource::Blend:
case ICorJitInfo::PgoSource::Text:
return true;
default:
Expand Down Expand Up @@ -2624,6 +2625,16 @@ PhaseStatus Compiler::fgIncorporateProfileData()
fgIncorporateEdgeCounts();
}

#ifdef DEBUG
// Optionally synthesize & blend
//
if ((JitConfig.JitSynthesizeCounts() == 3) && !compIsForInlining())
{
JITDUMP("Synthesizing profile data and blending it with the actual profile data\n");
ProfileSynthesis::Run(this, ProfileSynthesisOption::BlendLikelihoods);
}
#endif

// Scale data as appropriate
//
fgApplyProfileScale();
Expand Down Expand Up @@ -4890,14 +4901,15 @@ EARLY_EXIT:;
// Arguments:
// weight1 -- first weight
// weight2 -- second weight
// epsilon -- maximum absolute difference for weights to be considered equal
//
// Notes:
// In most cases you should probably call fgProfileWeightsConsistent instead
// of this method.
//
bool Compiler::fgProfileWeightsEqual(weight_t weight1, weight_t weight2)
bool Compiler::fgProfileWeightsEqual(weight_t weight1, weight_t weight2, weight_t epsilon)
{
return fabs(weight1 - weight2) < 0.01;
return fabs(weight1 - weight2) <= epsilon;
}

//------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit bbc5634

Please sign in to comment.