1
1
using System ;
2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
+ using BenchmarkDotNet . Analysers ;
4
5
using BenchmarkDotNet . Attributes ;
5
6
using BenchmarkDotNet . Configs ;
6
7
using BenchmarkDotNet . Diagnosers ;
10
11
using BenchmarkDotNet . Reports ;
11
12
using BenchmarkDotNet . Tests . XUnit ;
12
13
using BenchmarkDotNet . Toolchains . InProcess . Emit ;
14
+ using Perfolizer . Horology ;
13
15
using Xunit ;
14
16
using Xunit . Abstractions ;
15
17
@@ -20,6 +22,8 @@ public class ExpectedBenchmarkResultsTests : BenchmarkTestExecutor
20
22
// NativeAot takes a long time to build, so not including it in these tests.
21
23
// We also don't test InProcessNoEmitToolchain because it is known to be less accurate than code-gen toolchains.
22
24
25
+ private static readonly TimeInterval FallbackCpuResolutionValue = TimeInterval . FromNanoseconds ( 0.2d ) ;
26
+
23
27
public ExpectedBenchmarkResultsTests ( ITestOutputHelper output ) : base ( output ) { }
24
28
25
29
private static IEnumerable < Type > EmptyBenchmarkTypes ( ) =>
@@ -104,21 +108,25 @@ private void AssertZeroResults(Type benchmarkType, IConfig config)
104
108
. AddDiagnoser ( new MemoryDiagnoser ( new MemoryDiagnoserConfig ( false ) ) )
105
109
) ;
106
110
107
- var cpuGhz = RuntimeInformation . GetCpuInfo ( ) . MaxFrequency . Value . ToGHz ( ) ;
111
+ var cpuResolution = RuntimeInformation . GetCpuInfo ( ) . MaxFrequency ? . ToResolution ( ) ?? FallbackCpuResolutionValue ;
112
+ var cpuGhz = cpuResolution . ToFrequency ( ) . ToGHz ( ) ;
108
113
109
114
foreach ( var report in summary . Reports )
110
115
{
111
- Assert . True ( cpuGhz * report . ResultStatistics . Mean < 1 , $ "Actual time was greater than 1 clock cycle.") ;
112
-
113
- var overheadTime = report . AllMeasurements
116
+ var workloadTimes = report . AllMeasurements
114
117
. Where ( m => m . IsOverhead ( ) && m . IterationStage == Engines . IterationStage . Actual )
115
118
. Select ( m => m . GetAverageTime ( ) . Nanoseconds )
116
- . Average ( ) ;
117
-
118
- var workloadTime = report . AllMeasurements
119
- . Where ( m => m . IsWorkload ( ) && m . IterationStage == Engines . IterationStage . Actual )
119
+ . ToArray ( ) ;
120
+ var overheadTimes = report . AllMeasurements
121
+ . Where ( m => m . IsOverhead ( ) && m . IterationStage == Engines . IterationStage . Actual )
120
122
. Select ( m => m . GetAverageTime ( ) . Nanoseconds )
121
- . Average ( ) ;
123
+ . ToArray ( ) ;
124
+
125
+ bool isZero = ZeroMeasurementHelper . CheckZeroMeasurementTwoSamples ( workloadTimes , overheadTimes ) ;
126
+ Assert . True ( isZero , $ "Actual time was not 0.") ;
127
+
128
+ var workloadTime = workloadTimes . Average ( ) ;
129
+ var overheadTime = overheadTimes . Average ( ) ;
122
130
123
131
// Allow for 1 cpu cycle variance
124
132
Assert . True ( overheadTime * cpuGhz < workloadTime * cpuGhz + 1 , "Overhead took more time than workload." ) ;
@@ -165,21 +173,25 @@ private void AssertLargeStructResults(IConfig config)
165
173
. AddDiagnoser ( new MemoryDiagnoser ( new MemoryDiagnoserConfig ( false ) ) )
166
174
) ;
167
175
168
- var cpuGhz = RuntimeInformation . GetCpuInfo ( ) . MaxFrequency . Value . ToGHz ( ) ;
176
+ var cpuResolution = RuntimeInformation . GetCpuInfo ( ) . MaxFrequency ? . ToResolution ( ) ?? FallbackCpuResolutionValue ;
177
+ var cpuGhz = cpuResolution . ToFrequency ( ) . ToGHz ( ) ;
169
178
170
179
foreach ( var report in summary . Reports )
171
180
{
172
- Assert . True ( cpuGhz * report . ResultStatistics . Mean >= 1 , $ "Actual time was less than 1 clock cycle.") ;
173
-
174
- var overheadTime = report . AllMeasurements
181
+ var workloadTimes = report . AllMeasurements
175
182
. Where ( m => m . IsOverhead ( ) && m . IterationStage == Engines . IterationStage . Actual )
176
183
. Select ( m => m . GetAverageTime ( ) . Nanoseconds )
177
- . Average ( ) ;
178
-
179
- var workloadTime = report . AllMeasurements
180
- . Where ( m => m . IsWorkload ( ) && m . IterationStage == Engines . IterationStage . Actual )
184
+ . ToArray ( ) ;
185
+ var overheadTimes = report . AllMeasurements
186
+ . Where ( m => m . IsOverhead ( ) && m . IterationStage == Engines . IterationStage . Actual )
181
187
. Select ( m => m . GetAverageTime ( ) . Nanoseconds )
182
- . Average ( ) ;
188
+ . ToArray ( ) ;
189
+
190
+ bool isZero = ZeroMeasurementHelper . CheckZeroMeasurementTwoSamples ( workloadTimes , overheadTimes ) ;
191
+ Assert . False ( isZero , $ "Actual time was 0.") ;
192
+
193
+ var workloadTime = workloadTimes . Average ( ) ;
194
+ var overheadTime = overheadTimes . Average ( ) ;
183
195
184
196
// Allow for 1 cpu cycle variance
185
197
Assert . True ( overheadTime * cpuGhz < workloadTime * cpuGhz + 1 , "Overhead took more time than workload." ) ;
0 commit comments