Created
April 3, 2022 23:58
-
-
Save tannergooding/c3bdb0b827b5cdac50621f3a5432d49b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.CompilerServices; | |
using System.Runtime.InteropServices; | |
using System.Runtime.Intrinsics; | |
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Running; | |
public unsafe class Proga | |
{ | |
static void Main(string[] args) | |
{ | |
BenchmarkSwitcher.FromAssembly(typeof(Proga).Assembly).Run(args); | |
} | |
} | |
[DisassemblyDiagnoser] | |
public unsafe class Benchmarks | |
{ | |
private const int length = 1024 * 16; | |
private static IntPtr pData16; | |
private static IntPtr pData32; | |
private static IntPtr pData64; | |
[GlobalSetup] | |
public void Setup() | |
{ | |
pData16 = (IntPtr)NativeMemory.AlignedAlloc(length, 16); | |
pData32 = (IntPtr)NativeMemory.AlignedAlloc(length, 32); | |
pData64 = (IntPtr)NativeMemory.AlignedAlloc(length, 64); | |
} | |
[GlobalCleanup] | |
public void Cleanup() | |
{ | |
NativeMemory.AlignedFree((void*)pData16); | |
NativeMemory.AlignedFree((void*)pData32); | |
NativeMemory.AlignedFree((void*)pData64); | |
} | |
public IEnumerable<object[]> TestData() | |
{ | |
yield return new object[] { length, (byte)42 }; | |
yield return new object[] { length, (byte)42 }; | |
yield return new object[] { length, (byte)42 }; | |
} | |
[Benchmark] | |
[ArgumentsSource(nameof(TestData))] | |
[MethodImpl(MethodImplOptions.AggressiveOptimization)] | |
public bool Contains_1xV128_16(int length, byte v) => Contains_1xV128(pData16, length, v); | |
[Benchmark] | |
[ArgumentsSource(nameof(TestData))] | |
[MethodImpl(MethodImplOptions.AggressiveOptimization)] | |
public bool Contains_1xV128_32(int length, byte v) => Contains_1xV128(pData32, length, v); | |
[Benchmark] | |
[ArgumentsSource(nameof(TestData))] | |
[MethodImpl(MethodImplOptions.AggressiveOptimization)] | |
public bool Contains_1xV128_64(int length, byte v) => Contains_1xV128(pData64, length, v); | |
public bool Contains_1xV128(IntPtr pData, int length, byte v) | |
{ | |
ref byte b = ref ((byte*)(pData))[0]; | |
nuint len = (nuint)length; | |
Vector128<byte> vVec = Vector128.Create(v); | |
for (nuint i = 0; i < len; i += (nuint)(Vector128<byte>.Count)) | |
{ | |
Vector128<byte> v1 = Vector128.LoadUnsafe(ref b, i); | |
if (Vector128.Equals(v1, vVec) == Vector128<byte>.Zero) | |
{ | |
continue; | |
} | |
return true; | |
} | |
return false; | |
} | |
[Benchmark] | |
[ArgumentsSource(nameof(TestData))] | |
[MethodImpl(MethodImplOptions.AggressiveOptimization)] | |
public bool Contains_2xV128_16(int length, byte v) => Contains_2xV128(pData16, length, v); | |
[Benchmark] | |
[ArgumentsSource(nameof(TestData))] | |
[MethodImpl(MethodImplOptions.AggressiveOptimization)] | |
public bool Contains_2xV128_32(int length, byte v) => Contains_2xV128(pData32, length, v); | |
[Benchmark] | |
[ArgumentsSource(nameof(TestData))] | |
[MethodImpl(MethodImplOptions.AggressiveOptimization)] | |
public bool Contains_2xV128_64(int length, byte v) => Contains_2xV128(pData64, length, v); | |
public bool Contains_2xV128(IntPtr pData, int length, byte v) | |
{ | |
ref byte b = ref ((byte*)(pData))[0]; | |
nuint len = (nuint)length; | |
Vector128<byte> vVec = Vector128.Create(v); | |
for (nuint i = 0; i < len; i += (nuint)(Vector128<byte>.Count * 2)) | |
{ | |
Vector128<byte> v1 = Vector128.LoadUnsafe(ref b, i); | |
Vector128<byte> v2 = Vector128.LoadUnsafe(ref b, i + (nuint)(Vector128<byte>.Count)); | |
if ((Vector128.Equals(v1, vVec) | Vector128.Equals(v2, vVec)) == Vector128<byte>.Zero) | |
{ | |
continue; | |
} | |
return true; | |
} | |
return false; | |
} | |
[Benchmark] | |
[ArgumentsSource(nameof(TestData))] | |
[MethodImpl(MethodImplOptions.AggressiveOptimization)] | |
public bool Contains_4xV128_16(int length, byte v) => Contains_4xV128(pData16, length, v); | |
[Benchmark] | |
[ArgumentsSource(nameof(TestData))] | |
[MethodImpl(MethodImplOptions.AggressiveOptimization)] | |
public bool Contains_4xV128_32(int length, byte v) => Contains_4xV128(pData32, length, v); | |
[Benchmark] | |
[ArgumentsSource(nameof(TestData))] | |
[MethodImpl(MethodImplOptions.AggressiveOptimization)] | |
public bool Contains_4xV128_64(int length, byte v) => Contains_4xV128(pData64, length, v); | |
public bool Contains_4xV128(IntPtr pData, int length, byte v) | |
{ | |
ref byte b = ref ((byte*)(pData))[0]; | |
nuint len = (nuint)length; | |
Vector128<byte> vVec = Vector128.Create(v); | |
for (nuint i = 0; i < len; i += (nuint)(Vector128<byte>.Count * 4)) | |
{ | |
if ((Vector128.Equals(Vector128.LoadUnsafe(ref b, i), vVec) | | |
Vector128.Equals(Vector128.LoadUnsafe(ref b, i + (nuint)(Vector128<byte>.Count)), vVec) | | |
Vector128.Equals(Vector128.LoadUnsafe(ref b, i + (nuint)(Vector128<byte>.Count * 2)), vVec) | | |
Vector128.Equals(Vector128.LoadUnsafe(ref b, i + (nuint)(Vector128<byte>.Count * 3)), vVec)) == Vector128<byte>.Zero) | |
{ | |
continue; | |
} | |
return true; | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment