Files
stgsharp/src/Nitload.Benchmark/SwissX86DisassemblyBench.cs
T

135 lines
4.4 KiB
C#

// -----------------------------------------------------------------------------
// file="SwissX86DisassemblyBench"
// Project: nFramework
// Copyright (c) Nitload.
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Diagnosers;
using Nitload.Common.HighPerformance.Memory;
using System;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86;
namespace Nitload.Benchmark
{
[DisassemblyDiagnoser(maxDepth: 3, exportHtml: true)]
public unsafe class SwissX86DisassemblyBench
{
private const int ResidentCount = 8192;
private byte* _buffer;
private L4.SwissTable _table;
private byte* _readBuffer;
private byte* _writeBuffer;
private L4.AddressSource _hitKey;
private L4.AddressSource _missKey;
private ulong _value;
[GlobalSetup]
public void Setup()
{
if (!Sse42.X64.IsSupported)
throw new PlatformNotSupportedException("The Swiss X86 disassembly probe requires x64 SSE4.2.");
_buffer = (byte*)NativeMemory.AlignedAlloc((nuint)L4.BufferSize, 64);
if (_buffer == null)
throw new OutOfMemoryException("Could not allocate Swiss disassembly buffers.");
_table = L4.SwissTable.Create(_buffer);
for (int index = 0; index < ResidentCount; index++)
{
if (!L4.SwissWriterX86.TryAddOrSet(_table.WriteBufferForLockFreeBenchmark,
MakeKey(index), (ulong)index + 1))
throw new InvalidOperationException($"Failed to seed Swiss key {index}.");
}
_table.SwapBuffers();
_readBuffer = _table.ReadBufferForLockFreeBenchmark;
_writeBuffer = _table.WriteBufferForLockFreeBenchmark;
for (int index = 0; index < ResidentCount; index++)
{
if (!L4.SwissWriterX86.TryAddOrSet(_writeBuffer, MakeKey(index), (ulong)index + 1))
throw new InvalidOperationException($"Failed to seed inactive Swiss key {index}.");
}
_hitKey = MakeKey(ResidentCount / 2);
_missKey = MakeKey(ResidentCount + 1);
_value = 0x1234_5678;
if (!L4.SwissReaderX86.TryGet(_readBuffer, _hitKey, out _) ||
L4.SwissReaderX86.TryGet(_readBuffer, _missKey, out _))
throw new InvalidOperationException("Swiss reader setup validation failed.");
}
[GlobalCleanup]
public void Cleanup()
{
_table.Dispose();
NativeMemory.AlignedFree(_buffer);
_buffer = null;
}
[Benchmark]
public bool RawReaderHit()
{
return L4.SwissReaderX86.TryGet(_readBuffer, _hitKey, out _value);
}
[Benchmark]
public bool RawReaderMiss()
{
return L4.SwissReaderX86.TryGet(_readBuffer, _missKey, out _value);
}
[Benchmark]
public bool RawWriterUpsertExisting()
{
return L4.SwissWriterX86.TryAddOrSet(_writeBuffer, _hitKey, _value);
}
[Benchmark]
public bool RawWriterRemoveAndReinsert()
{
return L4.SwissWriterX86.TryRemove(_writeBuffer, _hitKey, out ulong previousValue) &&
L4.SwissWriterX86.TryAddOrSet(_writeBuffer, _hitKey, previousValue);
}
[Benchmark]
public bool TableReaderHit()
{
return _table.TryGet(_hitKey, out _value);
}
[Benchmark]
public bool TableReaderMiss()
{
return _table.TryGet(_missKey, out _value);
}
[Benchmark]
public bool TableWriterUpsertExisting()
{
return _table.TryAddOrSet(_hitKey, _value);
}
[Benchmark]
public bool TableWriterRemoveAndReinsert()
{
return _table.TryRemove(_hitKey, out ulong previousValue) &&
_table.TryAddOrSet(_hitKey, previousValue);
}
private static L4.AddressSource MakeKey(int index)
{
return new L4.AddressSource
{
Address = 0x1000_0000UL + ((ulong)index * 64UL),
Description = ((ulong)index * 0x9e37_79b9UL) ^ 0xd1b5_4a32_d192_ed03UL
};
}
}
}