Add benchmarks to tests different ways of accessing arrays. Copypasted from http://stackoverflow.com/q/8497018/974487
This commit is contained in:
Родитель
7492c1bd65
Коммит
71369d3bdb
|
@ -77,6 +77,7 @@
|
|||
<Compile Include="JIT\Jit_LoopUnrolling.cs" />
|
||||
<Compile Include="JIT\Jit_RotateBits.cs" />
|
||||
<Compile Include="Other\Array_HeapAllocVsStackAlloc.cs" />
|
||||
<Compile Include="Other\Array_AccessNormalRefUnsafe.cs" />
|
||||
<Compile Include="Other\Math_DoubleSqrtAvx.cs" />
|
||||
<Compile Include="Other\Math_DoubleSqrt.cs" />
|
||||
<Compile Include="CPU\Cpu_Atomics.cs" />
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
using System;
|
||||
|
||||
using BenchmarkDotNet.Tasks;
|
||||
|
||||
namespace BenchmarkDotNet.Samples.Other
|
||||
{
|
||||
// See: http://stackoverflow.com/q/8497018/974487
|
||||
[BenchmarkTask(platform: BenchmarkPlatform.X86, jitVersion: BenchmarkJitVersion.LegacyJit)]
|
||||
[BenchmarkTask(platform: BenchmarkPlatform.X64, jitVersion: BenchmarkJitVersion.LegacyJit)]
|
||||
[BenchmarkTask(platform: BenchmarkPlatform.X64, jitVersion: BenchmarkJitVersion.RyuJit)]
|
||||
public class Array_AccessNormalRefUnsafe
|
||||
{
|
||||
private const int Iterations = 111;
|
||||
private static float[] buffer = new float[1024 * 1024 * 100];
|
||||
private static readonly int Len = buffer.Length;
|
||||
|
||||
[Benchmark]
|
||||
public void NormalAccess()
|
||||
{
|
||||
for (var i = 0; i < Iterations; i++)
|
||||
{
|
||||
Test.NormalAccess(buffer, i % Len);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void NormalRefAccess()
|
||||
{
|
||||
for (var i = 0; i < Iterations; i++)
|
||||
{
|
||||
Test.NormalRefAccess(ref buffer, i % Len);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void IntPtrAccessFixedOutsideLoop()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (float* ptr = &buffer[0])
|
||||
{
|
||||
for (var i = 0; i < Iterations; i++)
|
||||
{
|
||||
Test.IntPtrAccess((IntPtr)ptr, i % Len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void IntPtrMisalignedAccessFixedOutsideLoop()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (float* ptr = &buffer[0])
|
||||
{
|
||||
for (var i = 0; i < Iterations; i++)
|
||||
{
|
||||
Test.IntPtrMisalignedAccess((IntPtr)ptr, i % Len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void FixedAccessFixedInsideLoop()
|
||||
{
|
||||
for (var i = 0; i < Iterations; i++)
|
||||
{
|
||||
Test.FixedAccess(buffer, i % Len);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void PtrAccessFixedOutsideLoop()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (float* ptr = &buffer[0])
|
||||
{
|
||||
for (var i = 0; i < Iterations; i++)
|
||||
{
|
||||
Test.PtrAccess(ptr + (i % Len));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void PtrAccessFixedInsideLoop()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
for (var i = 0; i < Iterations; i++)
|
||||
{
|
||||
fixed (float* ptr = &buffer[i % Len])
|
||||
{
|
||||
Test.PtrAccess(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Test
|
||||
{
|
||||
public static void NormalAccess(float[] array, int index)
|
||||
{
|
||||
array[index] = array[index] + 2;
|
||||
}
|
||||
|
||||
public static void NormalRefAccess(ref float[] array, int index)
|
||||
{
|
||||
array[index] = array[index] + 2;
|
||||
}
|
||||
|
||||
public static void IntPtrAccess(IntPtr arrayPtr, int index)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
var array = (float*)IntPtr.Add(arrayPtr, index << 2);
|
||||
(*array) = (*array) + 2;
|
||||
}
|
||||
}
|
||||
|
||||
public static void IntPtrMisalignedAccess(IntPtr arrayPtr, int index)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
var array = (float*)IntPtr.Add(arrayPtr, index); // getting bits of a float
|
||||
(*array) = (*array) + 2;
|
||||
}
|
||||
}
|
||||
|
||||
public static void FixedAccess(float[] array, int index)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (float* ptr = &array[index])
|
||||
{
|
||||
(*ptr) = (*ptr) + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void PtrAccess(float* ptr)
|
||||
{
|
||||
(*ptr) = (*ptr) + 2;
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче