Adding LZC impls to benchmarks
This commit is contained in:
Родитель
a8c2a7ec24
Коммит
b14a3689d9
|
@ -6,12 +6,12 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.10.6" />
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.10.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net47'">
|
||||
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows">
|
||||
<Version>0.10.6</Version>
|
||||
<Version>0.10.8</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
|
||||
namespace HdrHistogram.Benchmarking.LeadingZeroCount
|
||||
{
|
||||
/// <summary>
|
||||
/// Contributed from @BBarry at https://github.com/HdrHistogram/HdrHistogram.NET/issues/42
|
||||
/// This variation perfoms very well. Similar profile to the "Current Impl".
|
||||
/// Faster on LegacyJIT/CLR, but much slower on RyuJIT (CLR & Core)
|
||||
/// </summary>
|
||||
public static class BBarry32BitIfShiftLookupWith64BitShiftBranch
|
||||
{
|
||||
private static readonly int[] Lookup;
|
||||
|
||||
static BBarry32BitIfShiftLookupWith64BitShiftBranch()
|
||||
{
|
||||
Lookup = new int[256];
|
||||
for (int i = 1; i < 256; ++i)
|
||||
{
|
||||
Lookup[i] = (int)(Math.Log(i) / Math.Log(2));
|
||||
}
|
||||
}
|
||||
public static int GetLeadingZeroCount(long value)
|
||||
{
|
||||
//TODO: Test this with just < instead of <=? i.e. const of int.Max+1;
|
||||
if (value <= int.MaxValue)
|
||||
return 63 - Log2((int)value);
|
||||
if (value <= uint.MaxValue)
|
||||
return 62 - Log2((int)(value >> 1));
|
||||
return 31 - Log2((int)(value >> 32));
|
||||
}
|
||||
|
||||
private static int Log2(int i)
|
||||
{
|
||||
if (i >= 0x1000000) { return Lookup[i >> 24] + 24; }
|
||||
if (i >= 0x10000) { return Lookup[i >> 16] + 16; }
|
||||
if (i >= 0x100) { return Lookup[i >> 8] + 8; }
|
||||
return Lookup[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contributed from @BBarry at https://github.com/HdrHistogram/HdrHistogram.NET/issues/42
|
||||
/// This variation perfoms very well. Similar profile to the "Current Impl".
|
||||
/// Faster on LegacyJIT/CLR, but much slower on RyuJIT (CLR & Core)
|
||||
/// </summary>
|
||||
public static class BBarry32BitIfShiftLookupWith64BitShiftBranch_2
|
||||
{
|
||||
private static readonly int[] Lookup;
|
||||
private const long IntOverflow = int.MaxValue + 1L;
|
||||
static BBarry32BitIfShiftLookupWith64BitShiftBranch_2()
|
||||
{
|
||||
Lookup = new int[256];
|
||||
for (int i = 1; i < 256; ++i)
|
||||
{
|
||||
Lookup[i] = (int)(Math.Log(i) / Math.Log(2));
|
||||
}
|
||||
}
|
||||
public static int GetLeadingZeroCount(long value)
|
||||
{
|
||||
if (value < IntOverflow)
|
||||
return 63 - Log2((uint)value);
|
||||
return 32 - Log2((uint)(value >> 31));
|
||||
}
|
||||
|
||||
private static int Log2(uint i)
|
||||
{
|
||||
if (i >= 0x1000000) { return Lookup[i >> 24] + 24; }
|
||||
if (i >= 0x10000) { return Lookup[i >> 16] + 16; }
|
||||
if (i >= 0x100) { return Lookup[i >> 8] + 8; }
|
||||
return Lookup[i];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
|
||||
namespace HdrHistogram.Benchmarking.LeadingZeroCount
|
||||
{
|
||||
/// <summary>
|
||||
/// Contributed from @BBarry at https://github.com/HdrHistogram/HdrHistogram.NET/issues/42
|
||||
/// This variation inlines all the shifts.
|
||||
/// It performs on par on LegacyJIT/CLR but significantly slower on RyuJIT.
|
||||
/// I assume it is because 7 branches vs the 4 above.
|
||||
/// </summary>
|
||||
internal static class BBarryIfShiftLookup
|
||||
{
|
||||
private static readonly int[] Lookup;
|
||||
|
||||
static BBarryIfShiftLookup()
|
||||
{
|
||||
Lookup = new int[256];
|
||||
for (int i = 1; i < 256; ++i)
|
||||
{
|
||||
Lookup[i] = (int)(Math.Log(i) / Math.Log(2));
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetLeadingZeroCount(long value)
|
||||
{
|
||||
if (value >= 0x100000000000000) { return 7 - Lookup[value >> 56]; }
|
||||
if (value >= 0x1000000000000) { return 15 - Lookup[value >> 48]; }
|
||||
if (value >= 0x10000000000) { return 23 - Lookup[value >> 40]; }
|
||||
if (value >= 0x100000000) { return 31 - Lookup[value >> 32]; }
|
||||
if (value >= 0x1000000) { return 39 - Lookup[value >> 24]; }
|
||||
if (value >= 0x10000) { return 47 - Lookup[value >> 16]; }
|
||||
if (value >= 0x100) { return 55 - Lookup[value >> 8]; }
|
||||
return 63 - Lookup[value];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,10 +27,23 @@ namespace HdrHistogram.Benchmarking.LeadingZeroCount
|
|||
/// </remarks>
|
||||
public abstract class LeadingZeroCountBenchmarkBase
|
||||
{
|
||||
private readonly int _maxBit;
|
||||
private readonly long[] _testValues;
|
||||
|
||||
protected LeadingZeroCountBenchmarkBase(int maxBit)
|
||||
{
|
||||
_maxBit = maxBit;
|
||||
|
||||
|
||||
//Create array of +ve numbers in the 'maxBit' bit range (i.e. 32 bit or 64bit)
|
||||
var expectedData = GenerateTestData(maxBit);
|
||||
_testValues = expectedData.Select(d => d.Value).ToArray();
|
||||
}
|
||||
|
||||
[BenchmarkDotNet.Attributes.GlobalSetup]
|
||||
public void OneOffValidationOfImplementations()
|
||||
{
|
||||
var expectedData = GenerateTestData(_maxBit);
|
||||
var functions = new Dictionary<string, Func<long, int>>
|
||||
{
|
||||
{"CurrentImpl", Bitwise.NumberOfLeadingZeros},
|
||||
|
@ -41,13 +54,11 @@ namespace HdrHistogram.Benchmarking.LeadingZeroCount
|
|||
{"DeBruijn64BitsBitScanner", LeadingZeroCount.DeBruijn64BitsBitScanner.GetLeadingZeroCount},
|
||||
{"DeBruijnMultiplication", LeadingZeroCount.DeBruijnMultiplication.GetLeadingZeroCount},
|
||||
{"DeBruijn128Bits", LeadingZeroCount.DeBruijn128Bits.GetLeadingZeroCount},
|
||||
{"BBarry32BitIfShiftLookupWith64BitShiftBranch", LeadingZeroCount.BBarry32BitIfShiftLookupWith64BitShiftBranch.GetLeadingZeroCount},
|
||||
{"BBarry32BitIfShiftLookupWith64BitShiftBranch_2", LeadingZeroCount.BBarry32BitIfShiftLookupWith64BitShiftBranch_2.GetLeadingZeroCount},
|
||||
{"BBarryIfShiftLookup", LeadingZeroCount.BBarryIfShiftLookup.GetLeadingZeroCount},
|
||||
};
|
||||
|
||||
//Create array of +ve numbers in the 'maxBit' bit range (i.e. 32 bit or 64bit)
|
||||
var expectedData = GenerateTestData(maxBit);
|
||||
ValidateImplementations(expectedData, functions);
|
||||
|
||||
_testValues = expectedData.Select(d => d.Value).ToArray();
|
||||
}
|
||||
|
||||
private static CalculationExpectation[] GenerateTestData(int maxBit)
|
||||
|
@ -157,7 +168,7 @@ namespace HdrHistogram.Benchmarking.LeadingZeroCount
|
|||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
[Benchmark]
|
||||
public int StringManipulation()
|
||||
{
|
||||
|
@ -168,7 +179,37 @@ namespace HdrHistogram.Benchmarking.LeadingZeroCount
|
|||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int BBarry_imp1()
|
||||
{
|
||||
var sum = 0;
|
||||
for (int i = 0; i < _testValues.Length; i++)
|
||||
{
|
||||
sum += LeadingZeroCount.BBarry32BitIfShiftLookupWith64BitShiftBranch.GetLeadingZeroCount(_testValues[i]);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
[Benchmark]
|
||||
public int BBarry_imp3()
|
||||
{
|
||||
var sum = 0;
|
||||
for (int i = 0; i < _testValues.Length; i++)
|
||||
{
|
||||
sum += LeadingZeroCount.BBarry32BitIfShiftLookupWith64BitShiftBranch_2.GetLeadingZeroCount(_testValues[i]);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
[Benchmark]
|
||||
public int BBarry_imp2()
|
||||
{
|
||||
var sum = 0;
|
||||
for (int i = 0; i < _testValues.Length; i++)
|
||||
{
|
||||
sum += LeadingZeroCount.BBarryIfShiftLookup.GetLeadingZeroCount(_testValues[i]);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
private class CalculationExpectation
|
||||
{
|
||||
public long Value { get; }
|
||||
|
|
|
@ -7,9 +7,15 @@ if [%1]==[] (
|
|||
)
|
||||
|
||||
dotnet restore -v=q
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
||||
|
||||
dotnet build -v=q -c=Release /p:Version=%SemVer%
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
||||
|
||||
dotnet test .\HdrHistogram.UnitTests\HdrHistogram.UnitTests.csproj -v=q --no-build -c=Release
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
||||
|
||||
dotnet pack .\HdrHistogram\HdrHistogram.csproj --no-build --include-symbols -c=Release /p:Version=%SemVer%
|
||||
dotnet pack .\HdrHistogram\HdrHistogram.csproj --no-build --include-symbols -c=Release /p:Version=%SemVer%
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
||||
|
||||
.\HdrHistogram.Benchmarking\bin\Release\net47\HdrHistogram.Benchmarking.exe *
|
Загрузка…
Ссылка в новой задаче