@@ -18,6 +18,10 @@ protected IterationData GetDummyIterationData(Action<long> dummyAction)
18
18
=> new ( IterationMode . Dummy , IterationStage . Jitting , iterationIndex , 1 , 1 , ( ) => { } , ( ) => { } , dummyAction ) ;
19
19
}
20
20
21
+ // We do our best to encourage the jit to fully promote methods to tier1, but tiered jit relies on heuristics,
22
+ // and we purposefully don't spend too much time in this stage, so we can't guarantee it.
23
+ // This should succeed for 99%+ of microbenchmarks. For any sufficiently short benchmarks where this fails,
24
+ // the following stages (Pilot and Warmup) will likely take it the rest of the way. Long-running benchmarks may never fully reach tier1.
21
25
internal sealed class EngineFirstJitStage : EngineJitStage
22
26
{
23
27
// It is not worth spending a long time in jit stage for macro-benchmarks.
@@ -66,10 +70,6 @@ internal override bool GetShouldRunIteration(List<Measurement> measurements, out
66
70
return false ;
67
71
}
68
72
69
- // We do our best to encourage the jit to fully promote methods to tier1, but tiered jit relies on heuristics,
70
- // and we purposefully don't spend too much time in this stage, so we can't guarantee it.
71
- // This should succeed for 99%+ of microbenchmarks. For any sufficiently short benchmarks where this fails,
72
- // the following stages (Pilot and Warmup) will likely take it the rest of the way. Long-running benchmarks may never fully reach tier1.
73
73
private IEnumerator < IterationData > EnumerateIterations ( )
74
74
{
75
75
++ iterationIndex ;
@@ -113,6 +113,12 @@ private IEnumerator<IterationData> EnumerateIterations()
113
113
114
114
MaybeSleep ( JitInfo . BackgroundCompilationDelay ) ;
115
115
}
116
+
117
+ // Empirical evidence shows that the first call after the method is tiered up takes longer,
118
+ // so we run an extra iteration to ensure the next stage gets a stable measurement.
119
+ ++ iterationIndex ;
120
+ yield return GetOverheadIterationData ( ) ;
121
+ yield return GetWorkloadIterationData ( ) ;
116
122
}
117
123
118
124
private IterationData GetOverheadIterationData ( )
@@ -121,7 +127,7 @@ private IterationData GetOverheadIterationData()
121
127
private IterationData GetWorkloadIterationData ( )
122
128
=> new ( IterationMode . Workload , IterationStage . Jitting , iterationIndex , 1 , 1 , parameters . IterationSetupAction , parameters . IterationCleanupAction , parameters . WorkloadActionNoUnroll ) ;
123
129
124
- private void MaybeSleep ( TimeSpan timeSpan )
130
+ private static void MaybeSleep ( TimeSpan timeSpan )
125
131
{
126
132
if ( timeSpan > TimeSpan . Zero )
127
133
{
0 commit comments