Skip to content

Commit a9b933d

Browse files
committed
Added UTF16 support + tests + benchmarks
1 parent a4eae24 commit a9b933d

13 files changed

+5213
-4250
lines changed

benchmark/Benchmark.cs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,83 @@ public unsafe void RunSSEDecodingBenchmarkWithAllocUTF16(string[] data, int[] le
344344
}
345345
}
346346

347+
public unsafe void RunAVX2DecodingBenchmarkUTF8(string[] data, int[] lengths)
348+
{
349+
for (int i = 0; i < FileContent.Length; i++)
350+
{
351+
//string s = FileContent[i];
352+
byte[] base64 = input[i];
353+
byte[] dataoutput = output[i];
354+
int bytesConsumed = 0;
355+
int bytesWritten = 0;
356+
SimdBase64.AVX2.Base64.DecodeFromBase64AVX2(base64.AsSpan(), dataoutput, out bytesConsumed, out bytesWritten, false);
357+
if (bytesWritten != lengths[i])
358+
{
359+
Console.WriteLine($"Error: {bytesWritten} != {lengths[i]}");
360+
#pragma warning disable CA2201
361+
throw new Exception("Error");
362+
}
363+
}
364+
}
365+
366+
public unsafe void RunAVX2DecodingBenchmarkUTF16(string[] data, int[] lengths)
367+
{
368+
for (int i = 0; i < FileContent.Length; i++)
369+
{
370+
string s = FileContent[i];
371+
ReadOnlySpan<char> base64 = s.AsSpan();
372+
byte[] dataoutput = output[i];
373+
int bytesConsumed = 0;
374+
int bytesWritten = 0;
375+
SimdBase64.AVX2.Base64.DecodeFromBase64AVX2(base64, dataoutput, out bytesConsumed, out bytesWritten, false);
376+
if (bytesWritten != lengths[i])
377+
{
378+
Console.WriteLine($"Error: {bytesWritten} != {lengths[i]}");
379+
#pragma warning disable CA2201
380+
throw new Exception("Error");
381+
}
382+
}
383+
}
384+
385+
386+
387+
public unsafe void RunAVX2DecodingBenchmarkWithAllocUTF8(string[] data, int[] lengths)
388+
{
389+
for (int i = 0; i < FileContent.Length; i++)
390+
{
391+
byte[] base64 = input[i];
392+
byte[] dataoutput = new byte[SimdBase64.Scalar.Base64.MaximalBinaryLengthFromBase64Scalar<byte>(base64.AsSpan())];
393+
int bytesConsumed = 0;
394+
int bytesWritten = 0;
395+
SimdBase64.AVX2.Base64.DecodeFromBase64AVX2(base64.AsSpan(), dataoutput, out bytesConsumed, out bytesWritten, false);
396+
if (bytesWritten != lengths[i])
397+
{
398+
Console.WriteLine($"Error: {bytesWritten} != {lengths[i]}");
399+
#pragma warning disable CA2201
400+
throw new Exception("Error");
401+
}
402+
}
403+
}
404+
405+
public unsafe void RunAVX2DecodingBenchmarkWithAllocUTF16(string[] data, int[] lengths)
406+
{
407+
for (int i = 0; i < FileContent.Length; i++)
408+
{
409+
string s = FileContent[i];
410+
char[] base64 = input16[i];
411+
byte[] dataoutput = new byte[SimdBase64.Scalar.Base64.MaximalBinaryLengthFromBase64Scalar<char>(base64.AsSpan())];
412+
int bytesConsumed = 0;
413+
int bytesWritten = 0;
414+
SimdBase64.AVX2.Base64.DecodeFromBase64AVX2(base64.AsSpan(), dataoutput, out bytesConsumed, out bytesWritten, false);
415+
if (bytesWritten != lengths[i])
416+
{
417+
Console.WriteLine($"Error: {bytesWritten} != {lengths[i]}");
418+
#pragma warning disable CA2201
419+
throw new Exception("Error");
420+
}
421+
}
422+
}
423+
347424

348425
public unsafe void RunARMDecodingBenchmarkUTF8(string[] data, int[] lengths)
349426
{
@@ -502,6 +579,23 @@ public unsafe void SSEDecodingRealDataWithAllocUTF8()
502579
RunSSEDecodingBenchmarkWithAllocUTF8(FileContent, DecodedLengths);
503580
}
504581

582+
[Benchmark]
583+
[BenchmarkCategory("AVX")]
584+
public unsafe void AVX2DecodingRealDataUTF8()
585+
{
586+
RunAVX2DecodingBenchmarkUTF8(FileContent, DecodedLengths);
587+
}
588+
589+
[Benchmark]
590+
[BenchmarkCategory("AVX")]
591+
public unsafe void AVX2DecodingRealDataWithAllocUTF8()
592+
{
593+
RunAVX2DecodingBenchmarkWithAllocUTF8(FileContent, DecodedLengths);
594+
}
595+
596+
597+
598+
505599
[Benchmark]
506600
[BenchmarkCategory("arm64")]
507601
public unsafe void ARMDecodingRealDataUTF8()
@@ -536,6 +630,21 @@ public unsafe void SSEDecodingRealDataWithAllocUTF16()
536630
{
537631
RunSSEDecodingBenchmarkWithAllocUTF16(FileContent, DecodedLengths);
538632
}
633+
634+
[Benchmark]
635+
[BenchmarkCategory("AVX2")]
636+
public unsafe void AVX2DecodingRealDataUTF16()
637+
{
638+
RunAVX2DecodingBenchmarkUTF16(FileContent, DecodedLengths);
639+
}
640+
641+
[Benchmark]
642+
[BenchmarkCategory("AVX2")]
643+
public unsafe void AVX2DecodingRealDataWithAllocUTF16()
644+
{
645+
RunAVX2DecodingBenchmarkWithAllocUTF16(FileContent, DecodedLengths);
646+
}
647+
539648
}
540649
#pragma warning disable CA1515
541650
public class Program

src/Base64.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
using System;
22
using System.Buffers;
33
using System.Runtime.CompilerServices;
4-
using System.Runtime.Intrinsics;
54
using System.Runtime.Intrinsics.Arm;
65
using System.Runtime.Intrinsics.X86;
76

87

98
namespace SimdBase64
109
{
11-
public static class Base64 {
10+
public static class Base64
11+
{
1212
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1313
public static int MaximalBinaryLengthFromBase64<T>(ReadOnlySpan<T> input)
1414
{
1515
return Scalar.Base64.MaximalBinaryLengthFromBase64Scalar(input);
1616
}
17-
public unsafe static OperationStatus DecodeFromBase64(ReadOnlySpan<byte> source, Span<byte> dest, out int bytesConsumed, out int bytesWritten, bool isUrl = false) {
17+
public unsafe static OperationStatus DecodeFromBase64(ReadOnlySpan<byte> source, Span<byte> dest, out int bytesConsumed, out int bytesWritten, bool isUrl = false)
18+
{
1819

1920
if (AdvSimd.Arm64.IsSupported && BitConverter.IsLittleEndian)
2021
{
@@ -38,12 +39,13 @@ public unsafe static OperationStatus DecodeFromBase64(ReadOnlySpan<byte> source,
3839

3940
}
4041

41-
public unsafe static OperationStatus DecodeFromBase64(ReadOnlySpan<char> source, Span<byte> dest, out int bytesConsumed, out int bytesWritten, bool isUrl = false) {
42+
public unsafe static OperationStatus DecodeFromBase64(ReadOnlySpan<char> source, Span<byte> dest, out int bytesConsumed, out int bytesWritten, bool isUrl = false)
43+
{
4244

4345
if (AdvSimd.Arm64.IsSupported && BitConverter.IsLittleEndian)
4446
{
4547
return Arm.Base64.DecodeFromBase64ARM(source, dest, out bytesConsumed, out bytesWritten, isUrl);
46-
}
48+
}
4749
// To be comleted
4850
//if (Vector512.IsHardwareAccelerated && Avx512Vbmi.IsSupported)
4951
//{

0 commit comments

Comments
 (0)