Skip to content

Commit bbc5634

Browse files
authored
JIT: profile synthesis blend and repair modes (#83567)
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.
1 parent 8a786a7 commit bbc5634

File tree

9 files changed

+424
-32
lines changed

9 files changed

+424
-32
lines changed

eng/pipelines/common/templates/runtimes/run-test-job.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ jobs:
542542
- fullpgo_random_gdv_edge
543543
- fullpgo_methodprofiling_always_optimized
544544
- syntheticpgo
545+
- syntheticpgo_blend
545546
${{ if in(parameters.testGroup, 'gc-longrunning') }}:
546547
longRunningGcTests: true
547548
scenarios:

eng/pipelines/libraries/run-test-job.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,5 @@ jobs:
201201
- jitosr_stress
202202
- jitosr_stress_random
203203
- syntheticpgo
204+
- syntheticpgo_blend
205+

src/coreclr/jit/block.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,6 +1867,12 @@ struct FlowEdge
18671867
m_likelihood = likelihood;
18681868
}
18691869

1870+
void clearLikelihood()
1871+
{
1872+
m_likelihood = 0.0;
1873+
INDEBUG(m_likelihoodSet = false);
1874+
}
1875+
18701876
#ifdef DEBUG
18711877
bool hasLikelihood() const
18721878
{

src/coreclr/jit/compiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5561,7 +5561,7 @@ class Compiler
55615561

55625562
#endif // DEBUG
55635563

5564-
static bool fgProfileWeightsEqual(weight_t weight1, weight_t weight2);
5564+
static bool fgProfileWeightsEqual(weight_t weight1, weight_t weight2, weight_t epsilon = 0.01);
55655565
static bool fgProfileWeightsConsistent(weight_t weight1, weight_t weight2);
55665566

55675567
static GenTree* fgGetFirstNode(GenTree* tree);

src/coreclr/jit/fgprofile.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ bool Compiler::fgHaveSufficientProfileWeights()
7878
{
7979
case ICorJitInfo::PgoSource::Dynamic:
8080
case ICorJitInfo::PgoSource::Text:
81+
case ICorJitInfo::PgoSource::Blend:
8182
return true;
8283

8384
case ICorJitInfo::PgoSource::Static:
84-
case ICorJitInfo::PgoSource::Blend:
8585
{
8686
// We sometimes call this very early, eg evaluating the prejit root.
8787
//
@@ -123,6 +123,7 @@ bool Compiler::fgHaveTrustedProfileWeights()
123123
switch (fgPgoSource)
124124
{
125125
case ICorJitInfo::PgoSource::Dynamic:
126+
case ICorJitInfo::PgoSource::Blend:
126127
case ICorJitInfo::PgoSource::Text:
127128
return true;
128129
default:
@@ -2624,6 +2625,16 @@ PhaseStatus Compiler::fgIncorporateProfileData()
26242625
fgIncorporateEdgeCounts();
26252626
}
26262627

2628+
#ifdef DEBUG
2629+
// Optionally synthesize & blend
2630+
//
2631+
if ((JitConfig.JitSynthesizeCounts() == 3) && !compIsForInlining())
2632+
{
2633+
JITDUMP("Synthesizing profile data and blending it with the actual profile data\n");
2634+
ProfileSynthesis::Run(this, ProfileSynthesisOption::BlendLikelihoods);
2635+
}
2636+
#endif
2637+
26272638
// Scale data as appropriate
26282639
//
26292640
fgApplyProfileScale();
@@ -4890,14 +4901,15 @@ EARLY_EXIT:;
48904901
// Arguments:
48914902
// weight1 -- first weight
48924903
// weight2 -- second weight
4904+
// epsilon -- maximum absolute difference for weights to be considered equal
48934905
//
48944906
// Notes:
48954907
// In most cases you should probably call fgProfileWeightsConsistent instead
48964908
// of this method.
48974909
//
4898-
bool Compiler::fgProfileWeightsEqual(weight_t weight1, weight_t weight2)
4910+
bool Compiler::fgProfileWeightsEqual(weight_t weight1, weight_t weight2, weight_t epsilon)
48994911
{
4900-
return fabs(weight1 - weight2) < 0.01;
4912+
return fabs(weight1 - weight2) <= epsilon;
49014913
}
49024914

49034915
//------------------------------------------------------------------------

0 commit comments

Comments
 (0)