Skip to content

Commit 90b8a60

Browse files
author
Daniel Lemire
committed
Improving the benchmark, so we can see all the implementations.
1 parent 889cd7e commit 90b8a60

File tree

3 files changed

+108
-17
lines changed

3 files changed

+108
-17
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ cd benchmark
4747
dotnet run -c Release
4848
```
4949

50+
To run just one benchmark, use a filter:
51+
52+
```
53+
cd benchmark
54+
dotnet run --configuration Release --filter "*Arabic-Lipsum*"
55+
```
56+
5057
If you are under macOS or Linux, you may want to run the benchmarks in privileged mode:
5158

5259
```

benchmark/Benchmark.cs

Lines changed: 98 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using BenchmarkDotNet.Running;
55
using BenchmarkDotNet.Configs;
66
using BenchmarkDotNet.Reports;
7+
using BenchmarkDotNet.Filters;
78
using System.Text;
89
using System.Runtime;
910
using System.Runtime.InteropServices;
@@ -12,7 +13,10 @@
1213
using System.Collections.Generic;
1314
using System.Linq;
1415
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;
1620

1721

1822
namespace SimdUnicodeBenchmarks
@@ -47,6 +51,8 @@ public string GetValue(Summary summary, BenchmarkCase benchmarkCase)
4751
public UnitType UnitType { get; } = UnitType.Dimensionless;
4852
public string Legend { get; } = "The speed in gigabytes per second";
4953
}
54+
55+
5056
[SimpleJob(launchCount: 1, warmupCount: 3, iterationCount: 3)]
5157
[Config(typeof(Config))]
5258
public class RealDataBenchmark
@@ -56,7 +62,44 @@ private class Config : ManualConfig
5662
{
5763
public Config()
5864
{
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+
60103
}
61104
}
62105
// Parameters and variables for real data
@@ -128,42 +171,83 @@ public void Setup()
128171
}
129172

130173
[Benchmark]
174+
[BenchmarkCategory("default", "runtime")]
131175
public unsafe void DotnetRuntimeUtf8ValidationRealData()
132176
{
133177
RunDotnetRuntimeUtf8ValidationBenchmark(allLinesUtf8, DotnetRuntime.Utf8Utility.GetPointerToFirstInvalidByte);
134178
}
135179

136180
[Benchmark]
181+
[BenchmarkCategory("default")]
137182
public unsafe void SIMDUtf8ValidationRealData()
138183
{
139184
if (allLinesUtf8 != null)
140185
{
141186
RunUtf8ValidationBenchmark(allLinesUtf8, SimdUnicode.UTF8.GetPointerToFirstInvalidByte);
142187
}
143188
}
144-
}
145189

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()
150211
{
151-
if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
212+
if (allLinesUtf8 != null)
152213
{
153-
Console.WriteLine("ARM64 system detected.");
214+
RunUtf8ValidationBenchmark(allLinesUtf8, SimdUnicode.UTF8.GetPointerToFirstInvalidByteAvx2);
154215
}
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)
156224
{
157-
Console.WriteLine("X64 system detected (Intel, AMD,...).");
225+
RunUtf8ValidationBenchmark(allLinesUtf8, SimdUnicode.UTF8.GetPointerToFirstInvalidByteSse);
158226
}
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)
160235
{
161-
Console.WriteLine("Unrecognized system.");
236+
RunUtf8ValidationBenchmark(allLinesUtf8, SimdUnicode.UTF8.GetPointerToFirstInvalidByteAvx512);
162237
}
238+
}*/
163239

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+
{
164246
var config = DefaultConfig.Instance.WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(100));
165247
BenchmarkRunner.Run<RealDataBenchmark>(config);
166-
}
248+
}*/
249+
static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
250+
167251

168252
}
169253

src/UTF8.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,11 +465,11 @@ public static class UTF8
465465
//if (Vector512.IsHardwareAccelerated && Avx512Vbmi2.IsSupported)
466466
//{
467467
// return GetPointerToFirstInvalidByteAvx512(pInputBuffer, inputLength);
468-
//
468+
//GetPointerToFirstInvalidByteAvx2
469469
//}
470-
//if (Sse2.IsSupported)
470+
//if (Sse42.IsSupported)
471471
//{
472-
// return GetPointerToFirstInvalidByteSse2(pInputBuffer, inputLength);
472+
// return GetPointerToFirstInvalidByteSse(pInputBuffer, inputLength);
473473
//}
474474
return GetPointerToFirstInvalidByteScalar(pInputBuffer, inputLength);
475475
}

0 commit comments

Comments
 (0)