Browse Source

Add NormalSrcOver benchmark

pull/2359/head
James Jackson-South 3 years ago
parent
commit
c06da8c4bc
  1. 24
      tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs
  2. 68
      tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsSingleVector.cs

24
tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs

@ -12,9 +12,9 @@ namespace SixLabors.ImageSharp.Benchmarks;
public class PorterDuffBulkVsPixel public class PorterDuffBulkVsPixel
{ {
private Configuration Configuration => Configuration.Default; private static Configuration Configuration => Configuration.Default;
private void BulkVectorConvert<TPixel>( private static void BulkVectorConvert<TPixel>(
Span<TPixel> destination, Span<TPixel> destination,
Span<TPixel> background, Span<TPixel> background,
Span<TPixel> source, Span<TPixel> source,
@ -31,18 +31,18 @@ public class PorterDuffBulkVsPixel
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
PixelOperations<TPixel>.Instance.ToVector4(this.Configuration, background, backgroundSpan); PixelOperations<TPixel>.Instance.ToVector4(Configuration, background, backgroundSpan);
PixelOperations<TPixel>.Instance.ToVector4(this.Configuration, source, sourceSpan); PixelOperations<TPixel>.Instance.ToVector4(Configuration, source, sourceSpan);
for (int i = 0; i < destination.Length; i++) for (int i = 0; i < destination.Length; i++)
{ {
destinationSpan[i] = PorterDuffFunctions.NormalSrcOver(backgroundSpan[i], sourceSpan[i], amount[i]); destinationSpan[i] = PorterDuffFunctions.NormalSrcOver(backgroundSpan[i], sourceSpan[i], amount[i]);
} }
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.Configuration, destinationSpan, destination); PixelOperations<TPixel>.Instance.FromVector4Destructive(Configuration, destinationSpan, destination);
} }
private void BulkPixelConvert<TPixel>( private static void BulkPixelConvert<TPixel>(
Span<TPixel> destination, Span<TPixel> destination,
Span<TPixel> background, Span<TPixel> background,
Span<TPixel> source, Span<TPixel> source,
@ -60,9 +60,9 @@ public class PorterDuffBulkVsPixel
} }
[Benchmark(Description = "ImageSharp BulkVectorConvert")] [Benchmark(Description = "ImageSharp BulkVectorConvert")]
public Size BulkVectorConvert() public static Size BulkVectorConvert()
{ {
using var image = new Image<Rgba32>(800, 800); using Image<Rgba32> image = new(800, 800);
using IMemoryOwner<float> amounts = Configuration.Default.MemoryAllocator.Allocate<float>(image.Width); using IMemoryOwner<float> amounts = Configuration.Default.MemoryAllocator.Allocate<float>(image.Width);
amounts.GetSpan().Fill(1); amounts.GetSpan().Fill(1);
@ -70,23 +70,23 @@ public class PorterDuffBulkVsPixel
for (int y = 0; y < image.Height; y++) for (int y = 0; y < image.Height; y++)
{ {
Span<Rgba32> span = pixels.DangerousGetRowSpan(y); Span<Rgba32> span = pixels.DangerousGetRowSpan(y);
this.BulkVectorConvert(span, span, span, amounts.GetSpan()); BulkVectorConvert(span, span, span, amounts.GetSpan());
} }
return new Size(image.Width, image.Height); return new Size(image.Width, image.Height);
} }
[Benchmark(Description = "ImageSharp BulkPixelConvert")] [Benchmark(Description = "ImageSharp BulkPixelConvert")]
public Size BulkPixelConvert() public static Size BulkPixelConvert()
{ {
using var image = new Image<Rgba32>(800, 800); using Image<Rgba32> image = new(800, 800);
using IMemoryOwner<float> amounts = Configuration.Default.MemoryAllocator.Allocate<float>(image.Width); using IMemoryOwner<float> amounts = Configuration.Default.MemoryAllocator.Allocate<float>(image.Width);
amounts.GetSpan().Fill(1); amounts.GetSpan().Fill(1);
Buffer2D<Rgba32> pixels = image.GetRootFramePixelBuffer(); Buffer2D<Rgba32> pixels = image.GetRootFramePixelBuffer();
for (int y = 0; y < image.Height; y++) for (int y = 0; y < image.Height; y++)
{ {
Span<Rgba32> span = pixels.DangerousGetRowSpan(y); Span<Rgba32> span = pixels.DangerousGetRowSpan(y);
this.BulkPixelConvert(span, span, span, amounts.GetSpan()); BulkPixelConvert(span, span, span, amounts.GetSpan());
} }
return new Size(image.Width, image.Height); return new Size(image.Width, image.Height);

68
tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsSingleVector.cs

@ -0,0 +1,68 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using BenchmarkDotNet.Attributes;
using SixLabors.ImageSharp.PixelFormats.PixelBlenders;
namespace SixLabors.ImageSharp.Benchmarks.PixelBlenders;
public class PorterDuffBulkVsSingleVector
{
private Vector4[] backdrop;
private Vector4[] source;
[GlobalSetup]
public void Setup()
{
this.backdrop = new Vector4[8 * 20];
this.source = new Vector4[8 * 20];
FillRandom(this.backdrop);
FillRandom(this.source);
}
private static void FillRandom(Vector4[] arr)
{
Random rng = new();
for (int i = 0; i < arr.Length; i++)
{
arr[i].X = rng.NextSingle();
arr[i].Y = rng.NextSingle();
arr[i].Z = rng.NextSingle();
arr[i].W = rng.NextSingle();
}
}
[Benchmark(Description = "Scalar")]
public Vector4 OverlayValueFunction_Scalar()
{
Vector4 result = default;
for (int i = 0; i < this.backdrop.Length; i++)
{
result = PorterDuffFunctions.NormalSrcOver(this.backdrop[i], this.source[i], .5F);
}
return result;
}
[Benchmark(Description = "Avx")]
public Vector256<float> OverlayValueFunction_Avx()
{
ref Vector256<float> backdrop = ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference<Vector4>(this.backdrop));
ref Vector256<float> source = ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference<Vector4>(this.backdrop));
Vector256<float> result = default;
Vector256<float> opacity = Vector256.Create(.5F);
int count = this.backdrop.Length / 2;
for (int i = 0; i < count; i++)
{
result = PorterDuffFunctions.NormalSrcOver(Unsafe.Add(ref backdrop, i), Unsafe.Add(ref source, i), opacity);
}
return result;
}
}
Loading…
Cancel
Save