@@ -19,6 +19,7 @@ public class Engine : IEngine
19
19
20
20
[ PublicAPI ] public IHost Host { get ; }
21
21
[ PublicAPI ] public Action < long > WorkloadAction { get ; }
22
+ [ PublicAPI ] public Action < long > WorkloadActionNoUnroll { get ; }
22
23
[ PublicAPI ] public Action Dummy1Action { get ; }
23
24
[ PublicAPI ] public Action Dummy2Action { get ; }
24
25
[ PublicAPI ] public Action Dummy3Action { get ; }
@@ -44,19 +45,22 @@ public class Engine : IEngine
44
45
private readonly EnginePilotStage pilotStage ;
45
46
private readonly EngineWarmupStage warmupStage ;
46
47
private readonly EngineActualStage actualStage ;
47
- private readonly bool includeExtraStats ;
48
48
private readonly Random random ;
49
+ private readonly bool includeExtraStats , includeSurvivedMemory ;
50
+
51
+ private long ? survivedBytes ;
52
+ private bool survivedBytesMeasured ;
49
53
50
54
internal Engine (
51
55
IHost host ,
52
56
IResolver resolver ,
53
- Action dummy1Action , Action dummy2Action , Action dummy3Action , Action < long > overheadAction , Action < long > workloadAction , Job targetJob ,
57
+ Action dummy1Action , Action dummy2Action , Action dummy3Action , Action < long > overheadAction , Action < long > workloadAction , Action < long > workloadActionNoUnroll , Job targetJob ,
54
58
Action globalSetupAction , Action globalCleanupAction , Action iterationSetupAction , Action iterationCleanupAction , long operationsPerInvoke ,
55
- bool includeExtraStats , string benchmarkName )
59
+ bool includeExtraStats , bool includeSurvivedMemory , string benchmarkName )
56
60
{
57
-
58
61
Host = host ;
59
62
OverheadAction = overheadAction ;
63
+ WorkloadActionNoUnroll = workloadActionNoUnroll ;
60
64
Dummy1Action = dummy1Action ;
61
65
Dummy2Action = dummy2Action ;
62
66
Dummy3Action = dummy3Action ;
@@ -69,6 +73,7 @@ internal Engine(
69
73
OperationsPerInvoke = operationsPerInvoke ;
70
74
this . includeExtraStats = includeExtraStats ;
71
75
BenchmarkName = benchmarkName ;
76
+ this . includeSurvivedMemory = includeSurvivedMemory ;
72
77
73
78
Resolver = resolver ;
74
79
@@ -86,6 +91,14 @@ internal Engine(
86
91
random = new Random ( 12345 ) ; // we are using constant seed to try to get repeatable results
87
92
}
88
93
94
+ internal Engine WithInitialData ( Engine other )
95
+ {
96
+ // Copy the survived bytes from the other engine so we only measure it once.
97
+ survivedBytes = other . survivedBytes ;
98
+ survivedBytesMeasured = other . survivedBytesMeasured ;
99
+ return this ;
100
+ }
101
+
89
102
public void Dispose ( )
90
103
{
91
104
try
@@ -168,6 +181,17 @@ public Measurement RunIteration(IterationData data)
168
181
169
182
Span < byte > stackMemory = randomizeMemory ? stackalloc byte [ random . Next ( 32 ) ] : Span < byte > . Empty ;
170
183
184
+ bool needsSurvivedMeasurement = includeSurvivedMemory && ! isOverhead && ! survivedBytesMeasured ;
185
+ if ( needsSurvivedMeasurement && GcStats . InitTotalBytes ( ) )
186
+ {
187
+ // Measure survived bytes for only the first invocation.
188
+ survivedBytesMeasured = true ;
189
+ long beforeBytes = GcStats . GetTotalBytes ( ) ;
190
+ WorkloadActionNoUnroll ( 1 ) ;
191
+ long afterBytes = GcStats . GetTotalBytes ( ) ;
192
+ survivedBytes = afterBytes - beforeBytes ;
193
+ }
194
+
171
195
// Measure
172
196
var clock = Clock . Start ( ) ;
173
197
action ( invokeCount / unrollFactor ) ;
@@ -218,8 +242,8 @@ public Measurement RunIteration(IterationData data)
218
242
IterationCleanupAction ( ) ; // we run iteration cleanup after collecting GC stats
219
243
220
244
var totalOperationsCount = data . InvokeCount * OperationsPerInvoke ;
221
- GcStats gcStats = ( finalGcStats - initialGcStats ) . WithTotalOperations ( totalOperationsCount ) ;
222
- ThreadingStats threadingStats = ( finalThreadingStats - initialThreadingStats ) . WithTotalOperations ( data . InvokeCount * OperationsPerInvoke ) ;
245
+ GcStats gcStats = ( finalGcStats - initialGcStats ) . WithTotalOperationsAndSurvivedBytes ( totalOperationsCount , survivedBytes ) ;
246
+ ThreadingStats threadingStats = ( finalThreadingStats - initialThreadingStats ) . WithTotalOperations ( totalOperationsCount ) ;
223
247
224
248
return ( gcStats , threadingStats , exceptionsStats . ExceptionsCount / ( double ) totalOperationsCount ) ;
225
249
}
@@ -253,7 +277,7 @@ private void GcCollect()
253
277
ForceGcCollect ( ) ;
254
278
}
255
279
256
- private static void ForceGcCollect ( )
280
+ internal static void ForceGcCollect ( )
257
281
{
258
282
GC . Collect ( ) ;
259
283
GC . WaitForPendingFinalizers ( ) ;
0 commit comments