Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Most significant bit and bool-to-int conversions. #15

Merged
merged 3 commits into from
Jul 30, 2015
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Most significant bit and bool to int conversions.
  • Loading branch information
redknightlois committed Jul 29, 2015
commit 4d789cf3efccdf99fd6507e83422df4dc47e1db1
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
58 changes: 58 additions & 0 deletions BenchmarkDotNet.Samples/Jit_BoolToInt.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
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 const int N = 1001;
private readonly bool[] bits;

public Jit_BoolToInt()
{
bits = new bool[N];
for (int i = 0; i < N; i++)
bits[i] = i % 2 == 0;
}

[Benchmark]
public int Framework()
{
int sum = 0;
for (int i = 0; i < N; i++)
sum += Convert.ToInt32(bits[i]);

return sum;
}

[Benchmark]
public int IfThenElse()
{
int sum = 0;
for (int i = 0; i < N; i++)
sum += bits[i] ? 1 : 0;

return sum;
}

[Benchmark]
public int UnsafeConvert()
{
int sum = 0;
unsafe
{
for (int i = 0; i < N; i++)
{
bool v = bits[i];
sum += *(int*)(&v);
}
}
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