Browse Source

add benchmark results and fix PixelOperations

js/color-alpha-handling
Anton Firszov 5 years ago
parent
commit
02ac45971b
  1. 1
      src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs
  2. 1
      src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs
  3. 23
      src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
  4. 14
      tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs
  5. 4
      tests/ImageSharp.Tests/Common/SimdUtilsTests.cs

1
src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs

@ -30,6 +30,7 @@ namespace SixLabors.ImageSharp.PixelFormats
ReadOnlySpan<byte> blueChannel,
Span<Rgb24> destination)
{
Guard.NotNull(configuration, nameof(configuration));
int count = redChannel.Length;
Guard.IsTrue(greenChannel.Length == count, nameof(greenChannel), "Channels must be of same size!");
Guard.IsTrue(blueChannel.Length == count, nameof(blueChannel), "Channels must be of same size!");

1
src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs

@ -65,6 +65,7 @@ namespace SixLabors.ImageSharp.PixelFormats
ReadOnlySpan<byte> blueChannel,
Span<Rgba32> destination)
{
Guard.NotNull(configuration, nameof(configuration));
int count = redChannel.Length;
Guard.IsTrue(greenChannel.Length == count, nameof(greenChannel), "Channels must be of same size!");
Guard.IsTrue(blueChannel.Length == count, nameof(blueChannel), "Channels must be of same size!");

23
src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs

@ -4,6 +4,8 @@
using System;
using System.Buffers;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Memory;
@ -177,13 +179,26 @@ namespace SixLabors.ImageSharp.PixelFormats
Span<TPixel> destination)
{
Guard.NotNull(configuration, nameof(configuration));
int count = redChannel.Length;
Guard.IsTrue(greenChannel.Length == count, nameof(greenChannel), "Channels must be of same size!");
Guard.IsTrue(blueChannel.Length == count, nameof(blueChannel), "Channels must be of same size!");
Guard.IsTrue(destination.Length > count + 2, nameof(destination), "'destination' must contain a padding of 3 elements!");
Guard.DestinationShouldNotBeTooShort(redChannel, destination, nameof(destination));
for (int i = 0; i < destination.Length; i++)
{
var rgb24 = new Rgb24(redChannel[i], greenChannel[i], blueChannel[i]);
Rgb24 rgb24 = default;
ref byte r = ref MemoryMarshal.GetReference(redChannel);
ref byte g = ref MemoryMarshal.GetReference(greenChannel);
ref byte b = ref MemoryMarshal.GetReference(blueChannel);
ref TPixel d = ref MemoryMarshal.GetReference(destination);
destination[i].FromRgb24(rgb24);
for (int i = 0; i < count; i++)
{
rgb24.R = Unsafe.Add(ref r, i);
rgb24.G = Unsafe.Add(ref g, i);
rgb24.B = Unsafe.Add(ref b, i);
Unsafe.Add(ref d, i).FromRgb24(rgb24);
}
}
}

14
tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs

@ -268,5 +268,19 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion
public byte V0, V1, V2, V3;
}
#pragma warning restore
// Results @ Anton's PC, 2020 Dec 05
// .NET Core 3.1.1
// Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
//
// | Method | Count | Mean | Error | StdDev | Ratio | RatioSD |
// |--------------------------------- |------ |-----------:|---------:|---------:|------:|--------:|
// | Rgb24_Scalar_PerElement_Span | 1024 | 1,634.6 ns | 26.56 ns | 24.84 ns | 3.12 | 0.05 |
// | Rgb24_Scalar_PerElement_Unsafe | 1024 | 1,284.7 ns | 4.70 ns | 4.16 ns | 2.46 | 0.01 |
// | Rgb24_Scalar_PerElement_Batched8 | 1024 | 1,182.3 ns | 5.12 ns | 4.27 ns | 2.26 | 0.01 |
// | Rgb24_Scalar_PerElement_Batched4 | 1024 | 1,146.2 ns | 16.38 ns | 14.52 ns | 2.19 | 0.02 |
// | Rgba32_Avx2_Float | 1024 | 522.7 ns | 1.78 ns | 1.39 ns | 1.00 | 0.00 |
// | Rgba24_Avx2_Bytes | 1024 | 243.3 ns | 1.56 ns | 1.30 ns | 0.47 | 0.00 |
// | Rgba32_Avx2_Bytes | 1024 | 146.0 ns | 2.48 ns | 2.32 ns | 0.28 | 0.01 |
}
}

4
tests/ImageSharp.Tests/Common/SimdUtilsTests.cs

@ -443,10 +443,10 @@ namespace SixLabors.ImageSharp.Tests.Common
expected[i].FromRgb24(new Rgb24(r[i], g[i], b[i]));
}
TPixel[] actual = new TPixel[count];
TPixel[] actual = new TPixel[count + 3]; // padding for Rgb24 AVX2
packMethod(r, g, b, actual);
Assert.Equal(expected, actual);
Assert.True(expected.AsSpan().SequenceEqual(actual.AsSpan().Slice(0, count)));
}
private static void TestImpl_BulkConvertNormalizedFloatToByteClampOverflows(

Loading…
Cancel
Save