@@ -212,8 +212,6 @@ private ClockSpan Measure(Action<long> action, long invokeCount)
212
212
return clock . GetElapsed ( ) ;
213
213
}
214
214
215
- // Make sure tier0 jit doesn't cause any unexpected allocations in this method.
216
- [ MethodImpl ( CodeGenHelper . AggressiveOptimizationOption ) ]
217
215
private ( GcStats , ThreadingStats , double ) GetExtraStats ( IterationData data )
218
216
{
219
217
// Warm up the GetAllocatedBytes function before starting the actual measurement.
@@ -224,23 +222,33 @@ private ClockSpan Measure(Action<long> action, long invokeCount)
224
222
var initialThreadingStats = ThreadingStats . ReadInitial ( ) ; // this method might allocate
225
223
var exceptionsStats = new ExceptionsStats ( ) ; // allocates
226
224
exceptionsStats . StartListening ( ) ; // this method might allocate
227
- var initialGcStats = GcStats . ReadInitial ( ) ;
228
225
229
- WorkloadAction ( data . InvokeCount / data . UnrollFactor ) ;
226
+ // GC collect before measuring allocations, as we do not collect during the measurement.
227
+ ForceGcCollect ( ) ;
228
+ var gcStats = MeasureWithGc ( data . InvokeCount / data . UnrollFactor ) ;
230
229
231
- var finalGcStats = GcStats . ReadFinal ( ) ;
232
230
exceptionsStats . Stop ( ) ; // this method might (de)allocate
233
231
var finalThreadingStats = ThreadingStats . ReadFinal ( ) ;
234
232
235
233
IterationCleanupAction ( ) ; // we run iteration cleanup after collecting GC stats
236
234
237
235
var totalOperationsCount = data . InvokeCount * OperationsPerInvoke ;
238
- GcStats gcStats = ( finalGcStats - initialGcStats ) . WithTotalOperations ( totalOperationsCount ) ;
236
+ gcStats = gcStats . WithTotalOperations ( totalOperationsCount ) ;
239
237
ThreadingStats threadingStats = ( finalThreadingStats - initialThreadingStats ) . WithTotalOperations ( data . InvokeCount * OperationsPerInvoke ) ;
240
238
241
239
return ( gcStats , threadingStats , exceptionsStats . ExceptionsCount / ( double ) totalOperationsCount ) ;
242
240
}
243
241
242
+ // Isolate the allocation measurement and skip tier0 jit to make sure we don't get any unexpected allocations.
243
+ [ MethodImpl ( MethodImplOptions . NoInlining | CodeGenHelper . AggressiveOptimizationOption ) ]
244
+ private GcStats MeasureWithGc ( long invokeCount )
245
+ {
246
+ var initialGcStats = GcStats . ReadInitial ( ) ;
247
+ WorkloadAction ( invokeCount ) ;
248
+ var finalGcStats = GcStats . ReadFinal ( ) ;
249
+ return finalGcStats - initialGcStats ;
250
+ }
251
+
244
252
private void RandomizeManagedHeapMemory ( )
245
253
{
246
254
// invoke global cleanup before global setup
@@ -267,8 +275,6 @@ private void GcCollect()
267
275
ForceGcCollect ( ) ;
268
276
}
269
277
270
- // Make sure tier0 jit doesn't cause any unexpected allocations in this method.
271
- [ MethodImpl ( CodeGenHelper . AggressiveOptimizationOption ) ]
272
278
internal static void ForceGcCollect ( )
273
279
{
274
280
GC . Collect ( ) ;
0 commit comments