Browse Source

benchmark conversion steps separately

af/merge-core
Anton Firszov 7 years ago
parent
commit
63233c2516
  1. 66
      tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs
  2. 61
      tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs

66
tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs

@ -0,0 +1,66 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization
{
public class UInt32ToSingle
{
private float[] data;
private const int Count = 64;
[GlobalSetup]
public void Setup()
{
this.data = new float[Count];
}
[Benchmark(Baseline = true)]
public void MagicMethod()
{
ref Vector<float> b = ref Unsafe.As<float, Vector<float>>(ref this.data[0]);
int n = Count / Vector<float>.Count;
Vector<float> magick = new Vector<float>(32768.0f);
Vector<float> scale = new Vector<float>(255f) / new Vector<float>(256f);
for (int i = 0; i < n; i++)
{
// union { float f; uint32_t i; } u;
// u.f = 32768.0f + x * (255.0f / 256.0f);
// return (uint8_t)u.i;
ref Vector<float> d = ref Unsafe.Add(ref b, i);
Vector<float> x = d;
//x = Vector.Max(x, Vector<float>.Zero);
//x = Vector.Min(x, Vector<float>.One);
x = (x * scale) + magick;
d = x;
}
}
[Benchmark]
public void StandardSimd()
{
int n = Count / Vector<float>.Count;
ref Vector<float> b = ref Unsafe.As<float, Vector<float>>(ref this.data[0]);
var scale = new Vector<float>(1f / 255f);
for (int i = 0; i < n; i++)
{
ref Vector<float> df = ref Unsafe.Add(ref b, i);
Vector<uint> du = Unsafe.As<Vector<float>, Vector<uint>>(ref df);
Vector<float> v = Vector.ConvertToSingle(du);
v *= scale;
df = v;
}
}
}
}

61
tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs

@ -0,0 +1,61 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization
{
public class WidenBytesToUInt32
{
private byte[] source;
private uint[] dest;
private const int Count = 64;
[GlobalSetup]
public void Setup()
{
this.source = new byte[Count];
this.dest = new uint[Count];
}
[Benchmark(Baseline = true)]
public void Standard()
{
const int N = Count / 8;
ref SimdUtils.Octet.OfByte sBase = ref Unsafe.As<byte, SimdUtils.Octet.OfByte>(ref this.source[0]);
ref SimdUtils.Octet.OfUInt32 dBase = ref Unsafe.As<uint, SimdUtils.Octet.OfUInt32>(ref this.dest[0]);
for (int i = 0; i < N; i++)
{
Unsafe.Add(ref dBase, i).LoadFrom(ref Unsafe.Add(ref sBase, i));
}
}
[Benchmark]
public void Simd()
{
int n = Count / Vector<byte>.Count;
ref Vector<byte> sBase = ref Unsafe.As<byte, Vector<byte>>(ref this.source[0]);
ref Vector<uint> dBase = ref Unsafe.As<uint, Vector<uint>>(ref this.dest[0]);
for (int i = 0; i < n; i++)
{
Vector<byte> b = Unsafe.Add(ref sBase, i);
Vector.Widen(b, out Vector<ushort> s0, out Vector<ushort> s1);
Vector.Widen(s0, out Vector<uint> w0, out Vector<uint> w1);
Vector.Widen(s1, out Vector<uint> w2, out Vector<uint> w3);
ref Vector<uint> d = ref Unsafe.Add(ref dBase, i * 4);
d = w0;
Unsafe.Add(ref d, 1) = w1;
Unsafe.Add(ref d, 2) = w2;
Unsafe.Add(ref d, 3) = w3;
}
}
}
}
Loading…
Cancel
Save