Skip to content

Commit 5180e8a

Browse files
authored
JIT: don't set edge weights to zero for inconsistent profiles (#87947)
With the advent of scalable profile counters (or even with the old racing counters) counts might be approximate or inconsistent. When we run across a negative count during reconstruction, set the afflicted count to a small positive value instead of to zero, since zero has special meaning to the JIT. The aim is to reduce some of the benchmark instability we are seeing in #87324. Depending on exact counter values, we can see different sets of edge weights (and hence block weights) from run to run.
1 parent feb1fe2 commit 5180e8a

File tree

2 files changed

+16
-10
lines changed

2 files changed

+16
-10
lines changed

src/coreclr/jit/fgprofile.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3449,13 +3449,16 @@ void EfficientEdgeCountReconstructor::Solve()
34493449
"\n",
34503450
resolvedEdge->m_sourceBlock->bbNum, resolvedEdge->m_targetBlock->bbNum, weight);
34513451

3452-
// If we arrive at a negative count for this edge, set it to zero.
3452+
// If we arrive at a negative count for this edge, set it to a small fraction of the block weight.
3453+
//
3454+
// Note this can happen somewhat frequently because of inconsistent counts from
3455+
// scalable or racing counters.
34533456
//
34543457
if (weight < 0)
34553458
{
3456-
JITDUMP(" .... weight was negative, setting to zero\n");
34573459
NegativeCount();
3458-
weight = 0;
3460+
weight = info->m_weight * ProfileSynthesis::epsilon;
3461+
JITDUMP(" .... weight was negative, setting it to " FMT_WT "\n", weight);
34593462
}
34603463

34613464
resolvedEdge->m_weight = weight;
@@ -3496,13 +3499,16 @@ void EfficientEdgeCountReconstructor::Solve()
34963499
"\n",
34973500
resolvedEdge->m_sourceBlock->bbNum, resolvedEdge->m_targetBlock->bbNum, weight);
34983501

3499-
// If we arrive at a negative count for this edge, set it to zero.
3502+
// If we arrive at a negative count for this edge, set it to a small fraction of the block weight.
3503+
//
3504+
// Note this can happen somewhat frequently because of inconsistent counts from
3505+
// scalable or racing counters.
35003506
//
35013507
if (weight < 0)
35023508
{
3503-
JITDUMP(" .... weight was negative, setting to zero\n");
35043509
NegativeCount();
3505-
weight = 0;
3510+
weight = info->m_weight * ProfileSynthesis::epsilon;
3511+
JITDUMP(" .... weight was negative, setting it to " FMT_WT "\n", weight);
35063512
}
35073513

35083514
resolvedEdge->m_weight = weight;

src/coreclr/jit/fgprofilesynthesis.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class ProfileSynthesis
6464
p.Run(option);
6565
}
6666

67+
static constexpr weight_t epsilon = 0.001;
68+
6769
private:
6870
ProfileSynthesis(Compiler* compiler)
6971
: m_comp(compiler)
@@ -74,10 +76,8 @@ class ProfileSynthesis
7476
{
7577
}
7678

77-
static constexpr weight_t exceptionScale = 0.001;
78-
static constexpr weight_t blendFactor = 0.99;
79-
static constexpr weight_t epsilon = 0.001;
80-
79+
static constexpr weight_t exceptionScale = 0.001;
80+
static constexpr weight_t blendFactor = 0.99;
8181
static constexpr weight_t cappedLikelihood = 0.999;
8282
static constexpr weight_t returnLikelihood = 0.2;
8383
static constexpr weight_t ilNextLikelihood = 0.52;

0 commit comments

Comments
 (0)