8
8
9
9
namespace BenchmarkDotNet . Engines
10
10
{
11
- internal abstract class EngineJitStage ( int unrollFactor , EngineParameters parameters ) : EngineStage ( IterationStage . Jitting , IterationMode . Workload , parameters )
11
+ internal abstract class EngineJitStage ( EngineParameters parameters ) : EngineStage ( IterationStage . Jitting , IterationMode . Workload , parameters )
12
12
{
13
- protected readonly int unrollFactor = unrollFactor ;
14
13
protected readonly Action < long > dummy1Action = _ => parameters . Dummy1Action ( ) ;
15
14
protected readonly Action < long > dummy2Action = _ => parameters . Dummy2Action ( ) ;
16
15
protected readonly Action < long > dummy3Action = _ => parameters . Dummy3Action ( ) ;
@@ -24,26 +23,13 @@ internal sealed class EngineFirstJitStage : EngineJitStage
24
23
// It is not worth spending a long time in jit stage for macro-benchmarks.
25
24
private static readonly TimeInterval MaxTieringTime = TimeInterval . FromSeconds ( 10 ) ;
26
25
27
- internal bool didJitUnroll = false ;
28
26
internal bool didStopEarly = false ;
29
27
internal Measurement lastMeasurement ;
30
28
31
- private readonly Action < long > overheadAction ;
32
- private readonly Action < long > workloadAction ;
33
29
private readonly IEnumerator < IterationData > enumerator ;
34
30
35
- internal EngineFirstJitStage ( int unrollFactor , EngineParameters parameters ) : base ( unrollFactor , parameters )
31
+ internal EngineFirstJitStage ( EngineParameters parameters ) : base ( parameters )
36
32
{
37
- if ( unrollFactor != 1 )
38
- {
39
- overheadAction = parameters . OverheadActionUnroll ;
40
- workloadAction = parameters . WorkloadActionUnroll ;
41
- }
42
- else
43
- {
44
- overheadAction = parameters . OverheadActionNoUnroll ;
45
- workloadAction = parameters . WorkloadActionNoUnroll ;
46
- }
47
33
enumerator = EnumerateIterations ( ) ;
48
34
}
49
35
@@ -88,9 +74,9 @@ private IEnumerator<IterationData> EnumerateIterations()
88
74
{
89
75
++ iterationIndex ;
90
76
yield return GetDummyIterationData ( dummy1Action ) ;
91
- yield return GetOverheadNoUnrollIterationData ( ) ;
77
+ yield return GetOverheadIterationData ( ) ;
92
78
yield return GetDummyIterationData ( dummy2Action ) ;
93
- yield return GetWorkloadNoUnrollIterationData ( ) ;
79
+ yield return GetWorkloadIterationData ( ) ;
94
80
yield return GetDummyIterationData ( dummy3Action ) ;
95
81
96
82
// If the jit is not tiered, we're done.
@@ -102,103 +88,33 @@ private IEnumerator<IterationData> EnumerateIterations()
102
88
// Wait enough time for jit call counting to begin.
103
89
MaybeSleep ( JitInfo . TieredDelay ) ;
104
90
105
- // If the jit is configured for aggressive tiering, ignore how long it takes, and run 1 set of iterations per jit tier to fully promote the methods to tier1.
106
- if ( JitInfo . TieredCallCountThreshold == 1 )
107
- {
108
- ++ iterationIndex ;
109
- yield return GetOverheadNoUnrollIterationData ( ) ;
110
- yield return GetWorkloadNoUnrollIterationData ( ) ;
111
-
112
- MaybeSleep ( JitInfo . BackgroundCompilationDelay ) ;
113
-
114
- if ( JitInfo . IsDPGO )
115
- {
116
- ++ iterationIndex ;
117
- yield return GetOverheadNoUnrollIterationData ( ) ;
118
- yield return GetWorkloadNoUnrollIterationData ( ) ;
119
- }
120
-
121
- MaybeSleep ( JitInfo . BackgroundCompilationDelay ) ;
122
-
123
- yield break ;
124
- }
125
-
126
- // Otherwise, attempt to promote methods to tier1, but don't spend too much time in jit stage.
91
+ // Attempt to promote methods to tier1, but don't spend too much time in jit stage.
127
92
StartedClock startedClock = parameters . TargetJob . ResolveValue ( InfrastructureMode . ClockCharacteristic , parameters . Resolver ) . Start ( ) ;
128
93
129
- ++ iterationIndex ;
130
- yield return GetOverheadNoUnrollIterationData ( ) ;
131
- yield return GetWorkloadNoUnrollIterationData ( ) ;
132
-
133
- if ( startedClock . GetElapsed ( ) . GetTimeValue ( ) >= MaxTieringTime )
134
- {
135
- didStopEarly = true ;
136
- yield break ;
137
- }
138
-
139
- int tier0CallCount = JitInfo . TieredCallCountThreshold - 1 ;
140
- // Run unroll method if it's not too many invocations.
141
- if ( unrollFactor <= tier0CallCount )
142
- {
143
- tier0CallCount -= unrollFactor ;
144
- ++ iterationIndex ;
145
- yield return GetOverheadUnrollIterationData ( ) ;
146
- yield return GetWorkloadUnrollIterationData ( ) ;
147
-
148
- didJitUnroll = unrollFactor != 1 ;
149
-
150
- if ( startedClock . GetElapsed ( ) . GetTimeValue ( ) >= MaxTieringTime )
151
- {
152
- didStopEarly = true ;
153
- yield break ;
154
- }
155
- }
156
-
157
- // Run the remaining iterations without unroll.
158
- for ( int i = 0 ; i < tier0CallCount ; ++ i )
159
- {
160
- ++ iterationIndex ;
161
- yield return GetOverheadNoUnrollIterationData ( ) ;
162
- yield return GetWorkloadNoUnrollIterationData ( ) ;
163
-
164
- if ( startedClock . GetElapsed ( ) . GetTimeValue ( ) >= MaxTieringTime )
165
- {
166
- didStopEarly = true ;
167
- yield break ;
168
- }
169
- }
170
-
171
- MaybeSleep ( JitInfo . BackgroundCompilationDelay ) ;
172
-
173
- if ( JitInfo . IsDPGO )
94
+ for ( int tierCount = JitInfo . IsDPGO ? 2 : 1 ; tierCount >= 0 ; -- tierCount )
174
95
{
175
- for ( int i = 0 ; i < JitInfo . TieredCallCountThreshold ; ++ i )
96
+ for ( int callCount = JitInfo . TieredCallCountThreshold ; callCount >= 0 ; -- callCount )
176
97
{
177
98
++ iterationIndex ;
178
- yield return GetOverheadNoUnrollIterationData ( ) ;
179
- yield return GetWorkloadNoUnrollIterationData ( ) ;
99
+ yield return GetOverheadIterationData ( ) ;
100
+ yield return GetWorkloadIterationData ( ) ;
180
101
181
- if ( startedClock . GetElapsed ( ) . GetTimeValue ( ) >= MaxTieringTime )
102
+ if ( ( tierCount + callCount ) > 0
103
+ && startedClock . GetElapsed ( ) . GetTimeValue ( ) >= MaxTieringTime )
182
104
{
183
105
didStopEarly = true ;
184
106
yield break ;
185
107
}
186
108
}
187
- }
188
109
189
- MaybeSleep ( JitInfo . BackgroundCompilationDelay ) ;
110
+ MaybeSleep ( JitInfo . BackgroundCompilationDelay ) ;
111
+ }
190
112
}
191
113
192
- private IterationData GetOverheadUnrollIterationData ( )
193
- => new ( IterationMode . Overhead , IterationStage . Jitting , iterationIndex , unrollFactor , unrollFactor , ( ) => { } , ( ) => { } , overheadAction ) ;
194
-
195
- private IterationData GetWorkloadUnrollIterationData ( )
196
- => new ( IterationMode . Workload , IterationStage . Jitting , iterationIndex , unrollFactor , unrollFactor , parameters . IterationSetupAction , parameters . IterationCleanupAction , workloadAction ) ;
197
-
198
- private IterationData GetOverheadNoUnrollIterationData ( )
114
+ private IterationData GetOverheadIterationData ( )
199
115
=> new ( IterationMode . Overhead , IterationStage . Jitting , iterationIndex , 1 , 1 , ( ) => { } , ( ) => { } , parameters . OverheadActionNoUnroll ) ;
200
116
201
- private IterationData GetWorkloadNoUnrollIterationData ( )
117
+ private IterationData GetWorkloadIterationData ( )
202
118
=> new ( IterationMode . Workload , IterationStage . Jitting , iterationIndex , 1 , 1 , parameters . IterationSetupAction , parameters . IterationCleanupAction , parameters . WorkloadActionNoUnroll ) ;
203
119
204
120
private void MaybeSleep ( TimeSpan timeSpan )
@@ -210,8 +126,10 @@ private void MaybeSleep(TimeSpan timeSpan)
210
126
}
211
127
}
212
128
213
- internal sealed class EngineSecondJitStage ( int unrollFactor , EngineParameters parameters ) : EngineJitStage ( unrollFactor , parameters )
129
+ internal sealed class EngineSecondJitStage ( int unrollFactor , EngineParameters parameters ) : EngineJitStage ( parameters )
214
130
{
131
+ private readonly int unrollFactor = unrollFactor ;
132
+
215
133
internal override List < Measurement > GetMeasurementList ( ) => new ( GetMaxCallCount ( ) ) ;
216
134
217
135
private static int GetMaxCallCount ( )
0 commit comments