From 9ab574c63369b3c68372ed28a3175e6735f09316 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 18 Oct 2018 23:13:44 +0200 Subject: [PATCH] benchmarks for TPixel -> Vector4 conversion --- .../General/PixelConversion/ITestPixel.cs | 4 + .../PixelConversion_ConvertFromVector4.cs | 9 ++ .../PixelConversion_ConvertToRgba32.cs | 2 +- ...vertToRgba32_AsPartOfCompositeOperation.cs | 14 +-- .../PixelConversion_ConvertToVector4.cs | 83 ++++++++++++++++ ...ertToVector4_AsPartOfCompositeOperation.cs | 95 +++++++++++++++++++ .../General/PixelConversion/TestArgb.cs | 15 +++ .../General/PixelConversion/TestRgba.cs | 15 +++ 8 files changed, 229 insertions(+), 8 deletions(-) create mode 100644 tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs create mode 100644 tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs index ede617032f..b5f339fb37 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs @@ -20,5 +20,9 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion Rgba32 ToRgba32(); void CopyToRgba32(ref Rgba32 dest); + + Vector4 ToVector4(); + + void CopyToVector4(ref Vector4 dest); } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs index 30af857b1d..d0c8a3045c 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs @@ -29,6 +29,15 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion this.v = p; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToVector4() => this.v; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyToVector4(ref Vector4 dest) + { + dest = this.v; + } + public void FromRgba32(Rgba32 source) => throw new System.NotImplementedException(); public void FromRgba32(ref Rgba32 source) => throw new System.NotImplementedException(); public void FromBytes(byte r, byte g, byte b, byte a) => throw new System.NotImplementedException(); diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs index 89b4031a85..d205e1e63e 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion private ConversionRunner permutedRunner; - [Params(128)] + [Params(32)] public int Count { get; set; } [GlobalSetup] diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs index a27f7c3a5d..fff9ae9bc7 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion private ConversionRunner permutedRunner; - [Params(128)] + [Params(32)] public int Count { get; set; } [GlobalSetup] @@ -104,10 +104,10 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion } // RESULTS: - // Method | Count | Mean | Error | StdDev | Scaled | ScaledSD | - // ----------------- |------ |-----------:|----------:|----------:|-------:|---------:| - // CompatibleRetval | 128 | 210.1 ns | 0.8443 ns | 0.7484 ns | 1.00 | 0.00 | - // CompatibleCopyTo | 128 | 140.1 ns | 0.4297 ns | 0.4019 ns | 0.67 | 0.00 | - // PermutedRetval | 128 | 1,044.6 ns | 3.7901 ns | 3.3599 ns | 4.97 | 0.02 | - // PermutedCopyTo | 128 | 140.3 ns | 0.6495 ns | 0.5757 ns | 0.67 | 0.00 | + // Method | Count | Mean | Error | StdDev | Scaled | ScaledSD | + // ----------------- |------ |----------:|----------:|----------:|-------:|---------:| + // CompatibleRetval | 32 | 53.05 ns | 0.1865 ns | 0.1557 ns | 1.00 | 0.00 | + // CompatibleCopyTo | 32 | 36.12 ns | 0.3596 ns | 0.3003 ns | 0.68 | 0.01 | + // PermutedRetval | 32 | 303.61 ns | 5.1697 ns | 4.8358 ns | 5.72 | 0.09 | + // PermutedCopyTo | 32 | 38.05 ns | 0.8053 ns | 1.2297 ns | 0.72 | 0.02 | } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs new file mode 100644 index 0000000000..29a1139912 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs @@ -0,0 +1,83 @@ +using System.Numerics; +using System.Runtime.CompilerServices; + +using BenchmarkDotNet.Attributes; + +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ + public class PixelConversion_ConvertToVector4 + { + struct ConversionRunner + where T : struct, ITestPixel + { + private T[] source; + + private Vector4[] dest; + + public ConversionRunner(int count) + { + this.source = new T[count]; + this.dest = new Vector4[count]; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RunRetvalConversion() + { + int count = this.source.Length; + + ref T sourceBaseRef = ref this.source[0]; + ref Vector4 destBaseRef = ref this.dest[0]; + + for (int i = 0; i < count; i++) + { + Unsafe.Add(ref destBaseRef, i) = Unsafe.Add(ref sourceBaseRef, i).ToVector4(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RunCopyToConversion() + { + int count = this.source.Length; + + ref T sourceBaseRef = ref this.source[0]; + ref Vector4 destBaseRef = ref this.dest[0]; + + for (int i = 0; i < count; i++) + { + Unsafe.Add(ref sourceBaseRef, i).CopyToVector4(ref Unsafe.Add(ref destBaseRef, i)); + } + } + } + + private ConversionRunner runner; + + [Params(32)] + public int Count { get; set; } + + [GlobalSetup] + public void Setup() + { + this.runner = new ConversionRunner(this.Count); + } + + [Benchmark(Baseline = true)] + public void UseRetval() + { + this.runner.RunRetvalConversion(); + } + + [Benchmark] + public void UseCopyTo() + { + this.runner.RunCopyToConversion(); + } + + // RESULTS: + // Method | Count | Mean | Error | StdDev | Scaled | + // ---------- |------ |---------:|----------:|----------:|-------:| + // UseRetval | 32 | 94.99 ns | 1.1199 ns | 0.9352 ns | 1.00 | + // UseCopyTo | 32 | 59.47 ns | 0.6104 ns | 0.5710 ns | 0.63 | + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs new file mode 100644 index 0000000000..e5eb5c6cad --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs @@ -0,0 +1,95 @@ +using System.Numerics; +using System.Runtime.CompilerServices; + +using BenchmarkDotNet.Attributes; + +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ + public class PixelConversion_ConvertToVector4_AsPartOfCompositeOperation + { + struct ConversionRunner + where T : struct, ITestPixel + { + private T[] source; + + private Vector4[] dest; + + public ConversionRunner(int count) + { + this.source = new T[count]; + this.dest = new Vector4[count]; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RunRetvalConversion() + { + int count = this.source.Length; + + ref T sourceBaseRef = ref this.source[0]; + ref Vector4 destBaseRef = ref this.dest[0]; + + Vector4 temp; + + for (int i = 0; i < count; i++) + { + temp = Unsafe.Add(ref sourceBaseRef, i).ToVector4(); + + // manipulate pixel before saving to dest buffer: + temp.W = 0; + + Unsafe.Add(ref destBaseRef, i) = temp; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RunCopyToConversion() + { + int count = this.source.Length; + + ref T sourceBaseRef = ref this.source[0]; + ref Vector4 destBaseRef = ref this.dest[0]; + + Vector4 temp = default; + + for (int i = 0; i < count; i++) + { + Unsafe.Add(ref sourceBaseRef, i).CopyToVector4(ref temp); + + // manipulate pixel before saving to dest buffer: + temp.W = 0; + + Unsafe.Add(ref destBaseRef, i) = temp; + } + } + } + + private ConversionRunner runner; + + [Params(32)] + public int Count { get; set; } + + [GlobalSetup] + public void Setup() + { + this.runner = new ConversionRunner(this.Count); + } + + [Benchmark(Baseline = true)] + public void UseRetval() + { + this.runner.RunRetvalConversion(); + } + + [Benchmark] + public void UseCopyTo() + { + this.runner.RunCopyToConversion(); + } + + // RESULTS: + // Method | Count | Mean | Error | StdDev | Scaled | + // ---------- |------ |----------:|----------:|----------:|-------:| + // UseRetval | 32 | 100.35 ns | 0.4844 ns | 0.4532 ns | 1.00 | + // UseCopyTo | 32 | 53.95 ns | 0.1269 ns | 0.1125 ns | 0.54 | + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs index ddac1d1052..61a7df81d6 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs @@ -70,5 +70,20 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion dest.B = this.b; dest.A = this.a; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToVector4() + { + return new Vector4(this.r, this.g, this.b, this.a); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyToVector4(ref Vector4 dest) + { + dest.X = this.r; + dest.Y = this.g; + dest.Z = this.b; + dest.W = this.a; + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs index b06e84063f..3da7fcc4cf 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs @@ -53,5 +53,20 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion { dest = Unsafe.As(ref this); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToVector4() + { + return new Vector4(this.r, this.g, this.b, this.a); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyToVector4(ref Vector4 dest) + { + dest.X = this.r; + dest.Y = this.g; + dest.Z = this.b; + dest.W = this.a; + } } } \ No newline at end of file