Skip to content

Commit

Permalink
Merge pull request #15 from redknightlois/master
Browse files Browse the repository at this point in the history
Most significant bit and bool-to-int conversions.
  • Loading branch information
AndreyAkinshin committed Jul 30, 2015
2 parents 44cbb0a + b16153d commit 52acca1
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 1 deletion.
139 changes: 139 additions & 0 deletions BenchmarkDotNet.Samples/Algo_MostSignificantBit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
using BenchmarkDotNet.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BenchmarkDotNet.Samples
{
[Task(platform: BenchmarkPlatform.X64, jitVersion: BenchmarkJitVersion.LegacyJit)]
[Task(platform: BenchmarkPlatform.X64, jitVersion: BenchmarkJitVersion.RyuJit)]
public class Algo_MostSignificantBit
{
private const int N = 4001;
private readonly int[] numbers;
private readonly Random random = new Random(42);

public Algo_MostSignificantBit()
{
numbers = new int[N];
for (int i = 0; i < N; i++)
numbers[i] = random.Next();
}

[Benchmark]
public int MostSignificantDeBruijn()
{
int counter = 0;
for (int i = 0; i < N; i++)
counter += BitHelper.MostSignificantDeBruijn(numbers[i]);
return counter;
}

[Benchmark]
public int MostSignificantNaive()
{
int counter = 0;
for (int i = 0; i < N; i++)
counter += BitHelper.MostSignificantNaive(numbers[i]);
return counter;
}

[Benchmark]
public int MostSignificantShifted()
{
int counter = 0;
for (int i = 0; i < N; i++)
counter += BitHelper.MostSignificantShifted(numbers[i]);
return counter;
}

[Benchmark]
public int MostSignificantBranched()
{
int counter = 0;
for (int i = 0; i < N; i++)
counter += BitHelper.MostSignificantBranched(numbers[i]);
return counter;
}

public static class BitHelper
{
// Code taken from http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn

private static readonly int[] MultiplyDeBruijnBitPosition = new int[]
{
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};

public static int MostSignificantDeBruijn(int v)
{
v |= v >> 1; // first round down to one less than a power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;

return MultiplyDeBruijnBitPosition[(uint)(v * 0x07C4ACDDU) >> 27];
}

public static int MostSignificantNaive(int n)
{
int r = 0;

n >>= 1;
while (n != 0)
{
r++;
n >>= 1;
}

return r;
}

private static readonly int[] BranchedValues = new int[] { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 };

public static int MostSignificantBranched(int x)
{
if (x == 0)
return 0;

int r = 0;
if ((x & 0xFFFF0000) != 0) { r += 16 / 1; x >>= 16 / 1; }
if ((x & 0x0000FF00) != 0) { r += 16 / 2; x >>= 16 / 2; }
if ((x & 0x000000F0) != 0) { r += 16 / 4; x >>= 16 / 4; }
return r + BranchedValues[x] - 1;
}


public static int MostSignificantShifted(int n)
{
uint v = (uint)n; // 32-bit value to find the log2 of
uint r; // result of log2(v) will go here
uint shift;

unsafe
{
bool cond = v > 0xFFFF;
r = *(uint*)(&cond) << 4;

v >>= (int)r;

cond = v > 0xFF;
shift = *(uint*)(&cond) << 3; v >>= (int)shift; r |= shift;

cond = v > 0xF;
shift = *(uint*)(&cond) << 2; v >>= (int)shift; r |= shift;

cond = v > 0x3;
shift = *(uint*)(&cond) << 1; v >>= (int)shift; r |= shift;

r |= (v >> 1);

return (int)r;
}
}
}
}
}
3 changes: 3 additions & 0 deletions BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>5</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
Expand All @@ -46,6 +47,7 @@
<ItemGroup>
<Compile Include="Algo_BitCount.cs" />
<Compile Include="Algo_Md5VsSha256.cs" />
<Compile Include="Algo_MostSignificantBit.cs" />
<Compile Include="Cpu_BranchPerdictor.cs" />
<Compile Include="Cpu_Ilp_Inc.cs" />
<Compile Include="Il_ReadonlyFields.cs" />
Expand All @@ -58,6 +60,7 @@
<Compile Include="Jit_Bce.cs" />
<Compile Include="Cpu_MatrixMultiplication.cs" />
<Compile Include="Cpu_Ilp_Max.cs" />
<Compile Include="Jit_BoolToInt.cs" />
<Compile Include="Jit_Inlining.cs" />
<Compile Include="Jit_InterfaceMethod.cs" />
<Compile Include="Jit_LoopUnrolling.cs" />
Expand Down
52 changes: 52 additions & 0 deletions BenchmarkDotNet.Samples/Jit_BoolToInt.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using BenchmarkDotNet.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BenchmarkDotNet.Samples
{
[Task(platform: BenchmarkPlatform.X64, jitVersion: BenchmarkJitVersion.LegacyJit)]
[Task(platform: BenchmarkPlatform.X64, jitVersion: BenchmarkJitVersion.RyuJit)]
public class Jit_BoolToInt
{
private bool first;
private bool second;

public Jit_BoolToInt()
{
first = true;
second = false;
}

[Benchmark]
public int Framework()
{
int sum = Convert.ToInt32(first);
sum += Convert.ToInt32(second);
return sum;
}

[Benchmark]
public int IfThenElse()
{
int sum = first ? 1 : 0;
sum += second ? 1 : 0;
return sum;
}

[Benchmark]
public int UnsafeConvert()
{
unsafe
{
bool v1 = first;
int sum = *(byte*)(&v1);

bool v2 = second;
sum += *(byte*)(&v2);
return sum;
}
}
}
}
2 changes: 2 additions & 0 deletions BenchmarkDotNet.Samples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ static void Main(string[] args)
typeof(Jit_LoopUnrolling),
typeof(Jit_ArraySumLoopUnrolling),
typeof(Jit_Inlining),
typeof(Jit_BoolToInt),
typeof(Jit_Bce),
typeof(Jit_InterfaceMethod),
typeof(Cpu_Ilp_Inc),
Expand All @@ -27,6 +28,7 @@ static void Main(string[] args)
typeof(Math_DoubleSqrt),
typeof(Math_DoubleSqrtAvx),
typeof(Algo_BitCount),
typeof(Algo_MostSignificantBit),
typeof(Algo_Md5VsSha256)
});
competitionSwitch.Run(args);
Expand Down
5 changes: 4 additions & 1 deletion BenchmarkDotNet.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.22823.1
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkDotNet", "BenchmarkDotNet\BenchmarkDotNet.csproj", "{0F20FA04-52D8-4DB9-8B39-909125396A87}"
EndProject
Expand All @@ -25,4 +25,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(CodealikeProperties) = postSolution
SolutionGuid = d2cbc5be-205d-41dd-a90d-d625822471e3
EndGlobalSection
EndGlobal

0 comments on commit 52acca1

Please sign in to comment.