From 4d931e60076d14efa33507782c76f203cbc0a53f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 11 Jul 2017 13:35:18 +0200 Subject: [PATCH] more benchmarks --- .../General/Vectorization/DivFloat.cs | 54 -------------- .../General/Vectorization/DivUInt32.cs | 54 -------------- .../General/Vectorization/Divide.cs | 69 ++++++++++++++++++ .../General/Vectorization/MulFloat.cs | 67 ------------------ .../General/Vectorization/MulUInt32.cs | 54 -------------- .../General/Vectorization/Multiply.cs | 50 +++++++++++++ .../Vectorization/SIMDBenchmarkBase.cs | 70 +++++++++++++++++++ .../Image/DecodeJpegMultiple.cs | 38 +++++++++- .../Image/MultiImageBenchmarkBase.cs | 2 +- 9 files changed, 226 insertions(+), 232 deletions(-) delete mode 100644 tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs delete mode 100644 tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs create mode 100644 tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs delete mode 100644 tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs delete mode 100644 tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs create mode 100644 tests/ImageSharp.Benchmarks/General/Vectorization/Multiply.cs create mode 100644 tests/ImageSharp.Benchmarks/General/Vectorization/SIMDBenchmarkBase.cs diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs deleted file mode 100644 index caadaaa347..0000000000 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs +++ /dev/null @@ -1,54 +0,0 @@ -namespace ImageSharp.Benchmarks.General.Vectorization -{ - using System.Numerics; - - using BenchmarkDotNet.Attributes; - - public class DivFloat - { - private float[] input; - - private float[] result; - - [Params(32)] - public int InputSize { get; set; } - - private float testValue; - - [GlobalSetup] - public void Setup() - { - this.input = new float[this.InputSize]; - this.result = new float[this.InputSize]; - this.testValue = 42; - - for (int i = 0; i < this.InputSize; i++) - { - this.input[i] = (uint)i; - } - } - - [Benchmark(Baseline = true)] - public void Standard() - { - float v = this.testValue; - for (int i = 0; i < this.input.Length; i++) - { - this.result[i] = this.input[i] / v; - } - } - - [Benchmark] - public void Simd() - { - Vector v = new Vector(this.testValue); - - for (int i = 0; i < this.input.Length; i += Vector.Count) - { - Vector a = new Vector(this.input, i); - a = a / v; - a.CopyTo(this.result, i); - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs deleted file mode 100644 index 6b3edb192b..0000000000 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs +++ /dev/null @@ -1,54 +0,0 @@ -namespace ImageSharp.Benchmarks.General.Vectorization -{ - using System.Numerics; - - using BenchmarkDotNet.Attributes; - - public class DivUInt32 - { - private uint[] input; - - private uint[] result; - - [Params(32)] - public int InputSize { get; set; } - - private uint testValue; - - [GlobalSetup] - public void Setup() - { - this.input = new uint[this.InputSize]; - this.result = new uint[this.InputSize]; - this.testValue = 42; - - for (int i = 0; i < this.InputSize; i++) - { - this.input[i] = (uint)i; - } - } - - [Benchmark(Baseline = true)] - public void Standard() - { - uint v = this.testValue; - for (int i = 0; i < this.input.Length; i++) - { - this.result[i] = this.input[i] / v; - } - } - - [Benchmark] - public void Simd() - { - Vector v = new Vector(this.testValue); - - for (int i = 0; i < this.input.Length; i += Vector.Count) - { - Vector a = new Vector(this.input, i); - a = a / v; - a.CopyTo(this.result, i); - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs new file mode 100644 index 0000000000..b384295570 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs @@ -0,0 +1,69 @@ +namespace ImageSharp.Benchmarks.General.Vectorization +{ + using System; + using System.Numerics; + + using BenchmarkDotNet.Attributes; + + public class DivFloat : SIMDBenchmarkBase.Divide + { + protected override float GetTestValue() => 42; + + [Benchmark(Baseline = true)] + public void Standard() + { + float v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = this.input[i] / v; + } + } + } + + public class Divide : SIMDBenchmarkBase.Divide + { + protected override uint GetTestValue() => 42; + + [Benchmark(Baseline = true)] + public void Standard() + { + uint v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = this.input[i] / v; + } + } + } + + public class DivInt32 : SIMDBenchmarkBase.Divide + { + protected override int GetTestValue() => 42; + + [Benchmark(Baseline = true)] + public void Standard() + { + int v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = this.input[i] / v; + } + } + } + + public class DivInt16 : SIMDBenchmarkBase.Divide + { + protected override short GetTestValue() => 42; + + protected override Vector GetTestVector() => new Vector(new short[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}); + + [Benchmark(Baseline = true)] + public void Standard() + { + short v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = (short)(this.input[i] / v); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs deleted file mode 100644 index e5ae49b2a6..0000000000 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs +++ /dev/null @@ -1,67 +0,0 @@ -namespace ImageSharp.Benchmarks.General.Vectorization -{ - using System.Numerics; - - using BenchmarkDotNet.Attributes; - - public class MulFloat - { - private float[] input; - - private float[] result; - - [Params(32)] - public int InputSize { get; set; } - - private float testValue; - - [GlobalSetup] - public void Setup() - { - this.input = new float[this.InputSize]; - this.result = new float[this.InputSize]; - this.testValue = 42; - - for (int i = 0; i < this.InputSize; i++) - { - this.input[i] = i; - } - } - - [Benchmark(Baseline = true)] - public void Standard() - { - float v = this.testValue; - for (int i = 0; i < this.input.Length; i++) - { - this.result[i] = this.input[i] * v; - } - } - - [Benchmark] - public void SimdMultiplyByVector() - { - Vector v = new Vector(this.testValue); - - for (int i = 0; i < this.input.Length; i += Vector.Count) - { - Vector a = new Vector(this.input, i); - a = a * v; - a.CopyTo(this.result, i); - } - } - - [Benchmark] - public void SimdMultiplyByScalar() - { - float v = this.testValue; - - for (int i = 0; i < this.input.Length; i += Vector.Count) - { - Vector a = new Vector(this.input, i); - a = a * v; - a.CopyTo(this.result, i); - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs deleted file mode 100644 index 532acc02d5..0000000000 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs +++ /dev/null @@ -1,54 +0,0 @@ -namespace ImageSharp.Benchmarks.General.Vectorization -{ - using System.Numerics; - - using BenchmarkDotNet.Attributes; - - public class MulUInt32 - { - private uint[] input; - - private uint[] result; - - [Params(32)] - public int InputSize { get; set; } - - private uint testValue; - - [GlobalSetup] - public void Setup() - { - this.input = new uint[this.InputSize]; - this.result = new uint[this.InputSize]; - this.testValue = 42; - - for (int i = 0; i < this.InputSize; i++) - { - this.input[i] = (uint)i; - } - } - - [Benchmark(Baseline = true)] - public void Standard() - { - uint v = this.testValue; - for (int i = 0; i < this.input.Length; i++) - { - this.result[i] = this.input[i] * v; - } - } - - [Benchmark] - public void Simd() - { - Vector v = new Vector(this.testValue); - - for (int i = 0; i < this.input.Length; i += Vector.Count) - { - Vector a = new Vector(this.input, i); - a = a * v; - a.CopyTo(this.result, i); - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/Multiply.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/Multiply.cs new file mode 100644 index 0000000000..d1b70f21b3 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/Multiply.cs @@ -0,0 +1,50 @@ +namespace ImageSharp.Benchmarks.General.Vectorization +{ + using System.Numerics; + using BenchmarkDotNet.Attributes; + + public class MulUInt32 : SIMDBenchmarkBase.Multiply + { + protected override uint GetTestValue() => 42u; + + [Benchmark(Baseline = true)] + public void Standard() + { + uint v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = this.input[i] * v; + } + } + } + + public class MulInt32 : SIMDBenchmarkBase.Multiply + { + [Benchmark(Baseline = true)] + public void Standard() + { + int v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = this.input[i] * v; + } + } + } + + public class MulInt16 : SIMDBenchmarkBase.Multiply + { + protected override short GetTestValue() => 42; + + protected override Vector GetTestVector() => new Vector(new short[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }); + + [Benchmark(Baseline = true)] + public void Standard() + { + short v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = (short)(this.input[i] * v); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/SIMDBenchmarkBase.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/SIMDBenchmarkBase.cs new file mode 100644 index 0000000000..76987dbd21 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/SIMDBenchmarkBase.cs @@ -0,0 +1,70 @@ +namespace ImageSharp.Benchmarks.General.Vectorization +{ + using System.Numerics; + using System.Runtime.CompilerServices; + + using BenchmarkDotNet.Attributes; + + public abstract class SIMDBenchmarkBase + where T : struct + { + protected T[] input; + + protected T[] result; + + protected T testValue; + + protected Vector testVector; + + protected virtual T GetTestValue() => default(T); + + protected virtual Vector GetTestVector() => new Vector(this.GetTestValue()); + + + [Params(32)] + public int InputSize { get; set; } + + [GlobalSetup] + public virtual void Setup() + { + this.input = new T[this.InputSize]; + this.result = new T[this.InputSize]; + this.testValue = this.GetTestValue(); + this.testVector = this.GetTestVector(); + } + + public abstract class Multiply : SIMDBenchmarkBase + { + [Benchmark] + public void Simd() + { + Vector v = this.testVector; + + for (int i = 0; i < this.input.Length; i += Vector.Count) + { + Vector a = Unsafe.As>(ref this.input[i]); + a = a * v; + Unsafe.As>(ref this.result[i]) = a; + } + } + } + + public abstract class Divide : SIMDBenchmarkBase + { + [Benchmark] + public void Simd() + { + Vector v = this.testVector; + + for (int i = 0; i < this.input.Length; i += Vector.Count) + { + Vector a = Unsafe.As>(ref this.input[i]); + a = a / v; + Unsafe.As>(ref this.result[i]) = a; + } + } + } + + + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Image/DecodeJpegMultiple.cs b/tests/ImageSharp.Benchmarks/Image/DecodeJpegMultiple.cs index 44c90d253d..ebcdf972ae 100644 --- a/tests/ImageSharp.Benchmarks/Image/DecodeJpegMultiple.cs +++ b/tests/ImageSharp.Benchmarks/Image/DecodeJpegMultiple.cs @@ -6,8 +6,13 @@ namespace ImageSharp.Benchmarks.Image { using System.Collections.Generic; + using System.IO; + using BenchmarkDotNet.Attributes; + using ImageSharp.Formats; + using ImageSharp.PixelFormats; + using CoreImage = ImageSharp.Image; [Config(typeof(Config.Short))] @@ -20,14 +25,23 @@ namespace ImageSharp.Benchmarks.Image protected override IEnumerable SearchPatterns => new[] { "*.jpg" }; - [Benchmark(Description = "DecodeJpegMultiple - ImageSharp")] - public void DecodeJpegImageSharp() + [Benchmark(Description = "DecodeJpegMultiple - ImageSharp NEW")] + public void DecodeJpegImageSharpNwq() { this.ForEachStream( ms => CoreImage.Load(ms) ); } + + [Benchmark(Description = "DecodeJpegMultiple - ImageSharp Original")] + public void DecodeJpegImageSharpOriginal() + { + this.ForEachStream( + ms => CoreImage.Load(ms, new OriginalJpegDecoder()) + ); + } + [Benchmark(Baseline = true, Description = "DecodeJpegMultiple - System.Drawing")] public void DecodeJpegSystemDrawing() { @@ -36,5 +50,25 @@ namespace ImageSharp.Benchmarks.Image ); } + + public sealed class OriginalJpegDecoder : IImageDecoder, IJpegDecoderOptions + { + /// + /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded. + /// + public bool IgnoreMetadata { get; set; } + + /// + public Image Decode(Configuration configuration, Stream stream) + where TPixel : struct, IPixel + { + Guard.NotNull(stream, "stream"); + + using (var decoder = new JpegDecoderCore(configuration, this)) + { + return decoder.Decode(stream); + } + } + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Image/MultiImageBenchmarkBase.cs b/tests/ImageSharp.Benchmarks/Image/MultiImageBenchmarkBase.cs index e01a5951ef..fcd72a9ba3 100644 --- a/tests/ImageSharp.Benchmarks/Image/MultiImageBenchmarkBase.cs +++ b/tests/ImageSharp.Benchmarks/Image/MultiImageBenchmarkBase.cs @@ -39,7 +39,7 @@ namespace ImageSharp.Benchmarks.Image [Params(InputImageCategory.AllImages, InputImageCategory.SmallImagesOnly, InputImageCategory.LargeImagesOnly)] public virtual InputImageCategory InputCategory { get; set; } - protected virtual string BaseFolder => "../ImageSharp.Tests/TestImages/Formats/"; + protected virtual string BaseFolder => "../../../../../../../../ImageSharp.Tests/TestImages/Formats/"; protected virtual IEnumerable SearchPatterns => new[] { "*.*" };