@@ -18,6 +18,10 @@ protected IterationData GetDummyIterationData(Action<long> dummyAction)
1818 => new ( IterationMode . Dummy , IterationStage . Jitting , iterationIndex , 1 , 1 , ( ) => { } , ( ) => { } , dummyAction ) ;
1919 }
2020
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.
2125 internal sealed class EngineFirstJitStage : EngineJitStage
2226 {
2327 // 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
6670 return false ;
6771 }
6872
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.
7373 private IEnumerator < IterationData > EnumerateIterations ( )
7474 {
7575 ++ iterationIndex ;
@@ -113,6 +113,12 @@ private IEnumerator<IterationData> EnumerateIterations()
113113
114114 MaybeSleep ( JitInfo . BackgroundCompilationDelay ) ;
115115 }
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 ( ) ;
116122 }
117123
118124 private IterationData GetOverheadIterationData ( )
@@ -121,7 +127,7 @@ private IterationData GetOverheadIterationData()
121127 private IterationData GetWorkloadIterationData ( )
122128 => new ( IterationMode . Workload , IterationStage . Jitting , iterationIndex , 1 , 1 , parameters . IterationSetupAction , parameters . IterationCleanupAction , parameters . WorkloadActionNoUnroll ) ;
123129
124- private void MaybeSleep ( TimeSpan timeSpan )
130+ private static void MaybeSleep ( TimeSpan timeSpan )
125131 {
126132 if ( timeSpan > TimeSpan . Zero )
127133 {
0 commit comments