4
4
using BenchmarkDotNet . Running ;
5
5
using BenchmarkDotNet . Configs ;
6
6
using BenchmarkDotNet . Reports ;
7
+ using BenchmarkDotNet . Filters ;
7
8
using System . Text ;
8
9
using System . Runtime ;
9
10
using System . Runtime . InteropServices ;
12
13
using System . Collections . Generic ;
13
14
using System . Linq ;
14
15
using BenchmarkDotNet . Columns ;
15
-
16
+ using System . Runtime . Intrinsics ;
17
+ using System . Runtime . Intrinsics . X86 ;
18
+ using System . Runtime . Intrinsics . Arm ;
19
+ using System . Runtime . CompilerServices ;
16
20
17
21
18
22
namespace SimdUnicodeBenchmarks
@@ -47,6 +51,8 @@ public string GetValue(Summary summary, BenchmarkCase benchmarkCase)
47
51
public UnitType UnitType { get ; } = UnitType . Dimensionless ;
48
52
public string Legend { get ; } = "The speed in gigabytes per second" ;
49
53
}
54
+
55
+
50
56
[ SimpleJob ( launchCount : 1 , warmupCount : 3 , iterationCount : 3 ) ]
51
57
[ Config ( typeof ( Config ) ) ]
52
58
public class RealDataBenchmark
@@ -56,7 +62,44 @@ private class Config : ManualConfig
56
62
{
57
63
public Config ( )
58
64
{
59
- AddColumn ( new Speed ( ) ) ;
65
+ AddColumn ( new Speed ( ) ) ;
66
+
67
+
68
+ if ( RuntimeInformation . ProcessArchitecture == Architecture . Arm64 )
69
+ {
70
+ Console . WriteLine ( "ARM64 system detected." ) ;
71
+ AddFilter ( new AnyCategoriesFilter ( [ "arm64" , "scalar" , "runtime" ] ) ) ;
72
+
73
+ }
74
+ else if ( RuntimeInformation . ProcessArchitecture == Architecture . X64 )
75
+ {
76
+ if ( Vector512 . IsHardwareAccelerated && System . Runtime . Intrinsics . X86 . Avx512Vbmi . IsSupported )
77
+ {
78
+ Console . WriteLine ( "X64 system detected (Intel, AMD,...) with AVX-512 support." ) ;
79
+ AddFilter ( new AnyCategoriesFilter ( [ "avx512" , "avx" , "sse" , "scalar" , "runtime" ] ) ) ;
80
+ }
81
+ else if ( Avx2 . IsSupported )
82
+ {
83
+ Console . WriteLine ( "X64 system detected (Intel, AMD,...) with AVX2 support." ) ;
84
+ AddFilter ( new AnyCategoriesFilter ( [ "avx" , "sse" , "scalar" , "runtime" ] ) ) ;
85
+ }
86
+ else if ( Sse42 . IsSupported )
87
+ {
88
+ Console . WriteLine ( "X64 system detected (Intel, AMD,...) with Sse4.2 support." ) ;
89
+ AddFilter ( new AnyCategoriesFilter ( [ "sse" , "scalar" , "runtime" ] ) ) ;
90
+ }
91
+ else
92
+ {
93
+ Console . WriteLine ( "X64 system detected (Intel, AMD,...) without relevant SIMD support." ) ;
94
+ AddFilter ( new AnyCategoriesFilter ( [ "scalar" , "runtime" ] ) ) ;
95
+ }
96
+ }
97
+ else
98
+ {
99
+ AddFilter ( new AnyCategoriesFilter ( [ "scalar" , "runtime" ] ) ) ;
100
+
101
+ }
102
+
60
103
}
61
104
}
62
105
// Parameters and variables for real data
@@ -128,42 +171,83 @@ public void Setup()
128
171
}
129
172
130
173
[ Benchmark ]
174
+ [ BenchmarkCategory ( "default" , "runtime" ) ]
131
175
public unsafe void DotnetRuntimeUtf8ValidationRealData ( )
132
176
{
133
177
RunDotnetRuntimeUtf8ValidationBenchmark ( allLinesUtf8 , DotnetRuntime . Utf8Utility . GetPointerToFirstInvalidByte ) ;
134
178
}
135
179
136
180
[ Benchmark ]
181
+ [ BenchmarkCategory ( "default" ) ]
137
182
public unsafe void SIMDUtf8ValidationRealData ( )
138
183
{
139
184
if ( allLinesUtf8 != null )
140
185
{
141
186
RunUtf8ValidationBenchmark ( allLinesUtf8 , SimdUnicode . UTF8 . GetPointerToFirstInvalidByte ) ;
142
187
}
143
188
}
144
- }
145
189
146
- public class Program
147
- {
148
- // TODO: adopt BenchmarkSwitcher https://benchmarkdotnet.org/articles/guides/how-to-run.html
149
- public static void Main ( string [ ] args )
190
+ [ Benchmark ]
191
+ [ BenchmarkCategory ( "scalar" ) ]
192
+ public unsafe void Utf8ValidationRealDataScalar ( )
193
+ {
194
+ if ( allLinesUtf8 != null )
195
+ {
196
+ RunUtf8ValidationBenchmark ( allLinesUtf8 , SimdUnicode . UTF8 . GetPointerToFirstInvalidByteScalar ) ;
197
+ }
198
+ }
199
+ [ Benchmark ]
200
+ [ BenchmarkCategory ( "arm64" ) ]
201
+ public unsafe void SIMDUtf8ValidationRealDataArm64 ( )
202
+ {
203
+ if ( allLinesUtf8 != null )
204
+ {
205
+ RunUtf8ValidationBenchmark ( allLinesUtf8 , SimdUnicode . UTF8 . GetPointerToFirstInvalidByteArm64 ) ;
206
+ }
207
+ }
208
+ [ Benchmark ]
209
+ [ BenchmarkCategory ( "avx" ) ]
210
+ public unsafe void SIMDUtf8ValidationRealDataAvx2 ( )
150
211
{
151
- if ( RuntimeInformation . ProcessArchitecture == Architecture . Arm64 )
212
+ if ( allLinesUtf8 != null )
152
213
{
153
- Console . WriteLine ( "ARM64 system detected." ) ;
214
+ RunUtf8ValidationBenchmark ( allLinesUtf8 , SimdUnicode . UTF8 . GetPointerToFirstInvalidByteAvx2 ) ;
154
215
}
155
- else if ( RuntimeInformation . ProcessArchitecture == Architecture . X64 )
216
+ }
217
+ /*
218
+ // TODO: enable this benchmark when the SSE implementation is ready
219
+ [Benchmark]
220
+ [BenchmarkCategory("sse")]
221
+ public unsafe void SIMDUtf8ValidationRealDataSse()
222
+ {
223
+ if (allLinesUtf8 != null)
156
224
{
157
- Console . WriteLine ( "X64 system detected (Intel, AMD,...)." ) ;
225
+ RunUtf8ValidationBenchmark(allLinesUtf8, SimdUnicode.UTF8.GetPointerToFirstInvalidByteSse );
158
226
}
159
- else
227
+ }*/
228
+ /*
229
+ // TODO: enable this benchmark when the AVX-512 implementation is ready
230
+ [Benchmark]
231
+ [BenchmarkCategory("avx512")]
232
+ public unsafe void SIMDUtf8ValidationRealDataAvx512()
233
+ {
234
+ if (allLinesUtf8 != null)
160
235
{
161
- Console . WriteLine ( "Unrecognized system." ) ;
236
+ RunUtf8ValidationBenchmark(allLinesUtf8, SimdUnicode.UTF8.GetPointerToFirstInvalidByteAvx512 );
162
237
}
238
+ }*/
163
239
240
+ }
241
+ public class Program
242
+ {
243
+ // TODO: adopt BenchmarkSwitcher https://benchmarkdotnet.org/articles/guides/how-to-run.html
244
+ /*public static void Main(string[] args)
245
+ {
164
246
var config = DefaultConfig.Instance.WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(100));
165
247
BenchmarkRunner.Run<RealDataBenchmark>(config);
166
- }
248
+ }*/
249
+ static void Main ( string [ ] args ) => BenchmarkSwitcher . FromAssembly ( typeof ( Program ) . Assembly ) . Run ( args ) ;
250
+
167
251
168
252
}
169
253
0 commit comments