From 89bb9fe4224085dbf9be49889ff13ca6c34da270 Mon Sep 17 00:00:00 2001 From: Nicolas Portmann Date: Wed, 4 Nov 2020 21:14:54 +0100 Subject: [PATCH] Add benchmarks --- .../Codecs/Jpeg/CmykColorConversion.cs | 38 ++++++++++++ .../Codecs/Jpeg/ColorConversionBenchmark.cs | 61 +++++++++++++++++++ .../Codecs/Jpeg/GrayscaleColorConversion.cs | 38 ++++++++++++ .../Codecs/Jpeg/RgbColorConversion.cs | 38 ++++++++++++ .../Codecs/Jpeg/YCbCrColorConversion.cs | 53 ++-------------- .../Codecs/Jpeg/YccKColorConverter.cs | 38 ++++++++++++ 6 files changed, 217 insertions(+), 49 deletions(-) create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/CmykColorConversion.cs create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversionBenchmark.cs create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/GrayscaleColorConversion.cs create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/RgbColorConversion.cs create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/YccKColorConverter.cs diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/CmykColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/CmykColorConversion.cs new file mode 100644 index 000000000..64947408b --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/CmykColorConversion.cs @@ -0,0 +1,38 @@ +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg +{ + [Config(typeof(Config.ShortClr))] + public class CmykColorConversion : ColorConversionBenchmark + { + public CmykColorConversion() + : base(4) + { + } + + [Benchmark(Baseline = true)] + public void Scalar() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromCmykBasic(8).ConvertToRgba(values, this.output); + } + + [Benchmark] + public void SimdVector8() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromCmykVector8(8).ConvertToRgba(values, this.output); + } + + [Benchmark] + public void SimdVectorAvx2() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromCmykAvx2(8).ConvertToRgba(values, this.output); + } + } +} diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversionBenchmark.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversionBenchmark.cs new file mode 100644 index 000000000..046159128 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversionBenchmark.cs @@ -0,0 +1,61 @@ +using System; +using System.Numerics; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Memory; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg +{ + public abstract class ColorConversionBenchmark + { + private readonly int componentCount; + protected Buffer2D[] input; + protected Vector4[] output; + + protected ColorConversionBenchmark(int componentCount) + { + this.componentCount = componentCount; + } + + public const int Count = 128; + + [GlobalSetup] + public void Setup() + { + this.input = CreateRandomValues(componentCount, Count); + this.output = new Vector4[Count]; + } + + [GlobalCleanup] + public void Cleanup() + { + foreach (Buffer2D buffer in this.input) + { + buffer.Dispose(); + } + } + + private static Buffer2D[] CreateRandomValues( + int componentCount, + int inputBufferLength, + float minVal = 0f, + float maxVal = 255f) + { + var rnd = new Random(42); + var buffers = new Buffer2D[componentCount]; + for (int i = 0; i < componentCount; i++) + { + var values = new float[inputBufferLength]; + + for (int j = 0; j < inputBufferLength; j++) + { + values[j] = ((float)rnd.NextDouble() * (maxVal - minVal)) + minVal; + } + + // no need to dispose when buffer is not array owner + buffers[i] = Configuration.Default.MemoryAllocator.Allocate2D(values.Length, 1); + } + + return buffers; + } + } +} diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/GrayscaleColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/GrayscaleColorConversion.cs new file mode 100644 index 000000000..ee4d7b1bd --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/GrayscaleColorConversion.cs @@ -0,0 +1,38 @@ +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg +{ + [Config(typeof(Config.ShortClr))] + public class GrayscaleColorConversion : ColorConversionBenchmark + { + public GrayscaleColorConversion() + : base(1) + { + } + + [Benchmark(Baseline = true)] + public void Scalar() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromGrayscaleBasic(8).ConvertToRgba(values, this.output); + } + + [Benchmark] + public void SimdVector8() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromGrayscaleVector8(8).ConvertToRgba(values, this.output); + } + + [Benchmark] + public void SimdVectorAvx2() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromGrayscaleAvx2(8).ConvertToRgba(values, this.output); + } + } +} diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/RgbColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/RgbColorConversion.cs new file mode 100644 index 000000000..6f20ffda2 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/RgbColorConversion.cs @@ -0,0 +1,38 @@ +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg +{ + [Config(typeof(Config.ShortClr))] + public class RgbColorConversion : ColorConversionBenchmark + { + public RgbColorConversion() + : base(3) + { + } + + [Benchmark(Baseline = true)] + public void Scalar() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromRgbBasic(8).ConvertToRgba(values, this.output); + } + + [Benchmark] + public void SimdVector8() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromRgbVector8(8).ConvertToRgba(values, this.output); + } + + [Benchmark] + public void SimdVectorAvx2() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromRgbAvx2(8).ConvertToRgba(values, this.output); + } + } +} diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs index 9b4b4568f..c17f14fe6 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs @@ -1,39 +1,18 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using System; -using System.Numerics; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters; -using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { [Config(typeof(Config.ShortClr))] - public class YCbCrColorConversion + public class YCbCrColorConversion : ColorConversionBenchmark { - private Buffer2D[] input; - - private Vector4[] output; - - public const int Count = 128; - - [GlobalSetup] - public void Setup() - { - this.input = CreateRandomValues(3, Count); - this.output = new Vector4[Count]; - } - - [GlobalCleanup] - public void Cleanup() + public YCbCrColorConversion() + : base(3) { - foreach (Buffer2D buffer in this.input) - { - buffer.Dispose(); - } } [Benchmark] @@ -45,7 +24,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg } [Benchmark(Baseline = true)] - public void SimdVector4() + public void SimdVector() { var values = new JpegColorConverter.ComponentValues(this.input, 0); @@ -67,29 +46,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverter.FromYCbCrAvx2(8).ConvertToRgba(values, this.output); } - - private static Buffer2D[] CreateRandomValues( - int componentCount, - int inputBufferLength, - float minVal = 0f, - float maxVal = 255f) - { - var rnd = new Random(42); - var buffers = new Buffer2D[componentCount]; - for (int i = 0; i < componentCount; i++) - { - var values = new float[inputBufferLength]; - - for (int j = 0; j < inputBufferLength; j++) - { - values[j] = ((float)rnd.NextDouble() * (maxVal - minVal)) + minVal; - } - - // no need to dispose when buffer is not array owner - buffers[i] = Configuration.Default.MemoryAllocator.Allocate2D(values.Length, 1); - } - - return buffers; - } } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YccKColorConverter.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YccKColorConverter.cs new file mode 100644 index 000000000..5357cecd2 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YccKColorConverter.cs @@ -0,0 +1,38 @@ +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg +{ + [Config(typeof(Config.ShortClr))] + public class YccKColorConverter : ColorConversionBenchmark + { + public YccKColorConverter() + : base(4) + { + } + + [Benchmark(Baseline = true)] + public void Scalar() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromYccKBasic(8).ConvertToRgba(values, this.output); + } + + [Benchmark] + public void SimdVector8() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromYccKVector8(8).ConvertToRgba(values, this.output); + } + + [Benchmark] + public void SimdVectorAvx2() + { + var values = new JpegColorConverter.ComponentValues(this.input, 0); + + new JpegColorConverter.FromYccKAvx2(8).ConvertToRgba(values, this.output); + } + } +}