From 63233c251688fbeeec5786d034fe003c5ea2584c Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 19 Oct 2018 13:38:03 +0200 Subject: [PATCH] benchmark conversion steps separately --- .../General/Vectorization/UInt32ToSingle.cs | 66 +++++++++++++++++++ .../Vectorization/WidenBytesToUInt32.cs | 61 +++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs create mode 100644 tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs new file mode 100644 index 000000000..4a4b939b6 --- /dev/null +++ b/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 b = ref Unsafe.As>(ref this.data[0]); + + int n = Count / Vector.Count; + + Vector magick = new Vector(32768.0f); + Vector scale = new Vector(255f) / new Vector(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 d = ref Unsafe.Add(ref b, i); + Vector x = d; + //x = Vector.Max(x, Vector.Zero); + //x = Vector.Min(x, Vector.One); + + x = (x * scale) + magick; + d = x; + } + } + + [Benchmark] + public void StandardSimd() + { + int n = Count / Vector.Count; + + ref Vector b = ref Unsafe.As>(ref this.data[0]); + + var scale = new Vector(1f / 255f); + + for (int i = 0; i < n; i++) + { + ref Vector df = ref Unsafe.Add(ref b, i); + Vector du = Unsafe.As, Vector>(ref df); + + Vector v = Vector.ConvertToSingle(du); + v *= scale; + df = v; + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs new file mode 100644 index 000000000..f71f6ec1b --- /dev/null +++ b/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(ref this.source[0]); + ref SimdUtils.Octet.OfUInt32 dBase = ref Unsafe.As(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.Count; + + ref Vector sBase = ref Unsafe.As>(ref this.source[0]); + ref Vector dBase = ref Unsafe.As>(ref this.dest[0]); + + for (int i = 0; i < n; i++) + { + Vector b = Unsafe.Add(ref sBase, i); + + Vector.Widen(b, out Vector s0, out Vector s1); + Vector.Widen(s0, out Vector w0, out Vector w1); + Vector.Widen(s1, out Vector w2, out Vector w3); + + ref Vector 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; + } + } + } +} \ No newline at end of file