Skip to content

Commit c06da8c

Browse files
Add NormalSrcOver benchmark
1 parent 6cb6bd4 commit c06da8c

File tree

2 files changed

+80
-12
lines changed

2 files changed

+80
-12
lines changed

tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ namespace SixLabors.ImageSharp.Benchmarks;
1212

1313
public class PorterDuffBulkVsPixel
1414
{
15-
private Configuration Configuration => Configuration.Default;
15+
private static Configuration Configuration => Configuration.Default;
1616

17-
private void BulkVectorConvert<TPixel>(
17+
private static void BulkVectorConvert<TPixel>(
1818
Span<TPixel> destination,
1919
Span<TPixel> background,
2020
Span<TPixel> source,
@@ -31,18 +31,18 @@ private void BulkVectorConvert<TPixel>(
3131
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
3232
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
3333

34-
PixelOperations<TPixel>.Instance.ToVector4(this.Configuration, background, backgroundSpan);
35-
PixelOperations<TPixel>.Instance.ToVector4(this.Configuration, source, sourceSpan);
34+
PixelOperations<TPixel>.Instance.ToVector4(Configuration, background, backgroundSpan);
35+
PixelOperations<TPixel>.Instance.ToVector4(Configuration, source, sourceSpan);
3636

3737
for (int i = 0; i < destination.Length; i++)
3838
{
3939
destinationSpan[i] = PorterDuffFunctions.NormalSrcOver(backgroundSpan[i], sourceSpan[i], amount[i]);
4040
}
4141

42-
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.Configuration, destinationSpan, destination);
42+
PixelOperations<TPixel>.Instance.FromVector4Destructive(Configuration, destinationSpan, destination);
4343
}
4444

45-
private void BulkPixelConvert<TPixel>(
45+
private static void BulkPixelConvert<TPixel>(
4646
Span<TPixel> destination,
4747
Span<TPixel> background,
4848
Span<TPixel> source,
@@ -60,33 +60,33 @@ private void BulkPixelConvert<TPixel>(
6060
}
6161

6262
[Benchmark(Description = "ImageSharp BulkVectorConvert")]
63-
public Size BulkVectorConvert()
63+
public static Size BulkVectorConvert()
6464
{
65-
using var image = new Image<Rgba32>(800, 800);
65+
using Image<Rgba32> image = new(800, 800);
6666
using IMemoryOwner<float> amounts = Configuration.Default.MemoryAllocator.Allocate<float>(image.Width);
6767
amounts.GetSpan().Fill(1);
6868

6969
Buffer2D<Rgba32> pixels = image.GetRootFramePixelBuffer();
7070
for (int y = 0; y < image.Height; y++)
7171
{
7272
Span<Rgba32> span = pixels.DangerousGetRowSpan(y);
73-
this.BulkVectorConvert(span, span, span, amounts.GetSpan());
73+
BulkVectorConvert(span, span, span, amounts.GetSpan());
7474
}
7575

7676
return new Size(image.Width, image.Height);
7777
}
7878

7979
[Benchmark(Description = "ImageSharp BulkPixelConvert")]
80-
public Size BulkPixelConvert()
80+
public static Size BulkPixelConvert()
8181
{
82-
using var image = new Image<Rgba32>(800, 800);
82+
using Image<Rgba32> image = new(800, 800);
8383
using IMemoryOwner<float> amounts = Configuration.Default.MemoryAllocator.Allocate<float>(image.Width);
8484
amounts.GetSpan().Fill(1);
8585
Buffer2D<Rgba32> pixels = image.GetRootFramePixelBuffer();
8686
for (int y = 0; y < image.Height; y++)
8787
{
8888
Span<Rgba32> span = pixels.DangerousGetRowSpan(y);
89-
this.BulkPixelConvert(span, span, span, amounts.GetSpan());
89+
BulkPixelConvert(span, span, span, amounts.GetSpan());
9090
}
9191

9292
return new Size(image.Width, image.Height);
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using System.Numerics;
5+
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
7+
using System.Runtime.Intrinsics;
8+
using BenchmarkDotNet.Attributes;
9+
using SixLabors.ImageSharp.PixelFormats.PixelBlenders;
10+
11+
namespace SixLabors.ImageSharp.Benchmarks.PixelBlenders;
12+
13+
public class PorterDuffBulkVsSingleVector
14+
{
15+
private Vector4[] backdrop;
16+
private Vector4[] source;
17+
18+
[GlobalSetup]
19+
public void Setup()
20+
{
21+
this.backdrop = new Vector4[8 * 20];
22+
this.source = new Vector4[8 * 20];
23+
24+
FillRandom(this.backdrop);
25+
FillRandom(this.source);
26+
}
27+
28+
private static void FillRandom(Vector4[] arr)
29+
{
30+
Random rng = new();
31+
for (int i = 0; i < arr.Length; i++)
32+
{
33+
arr[i].X = rng.NextSingle();
34+
arr[i].Y = rng.NextSingle();
35+
arr[i].Z = rng.NextSingle();
36+
arr[i].W = rng.NextSingle();
37+
}
38+
}
39+
40+
[Benchmark(Description = "Scalar")]
41+
public Vector4 OverlayValueFunction_Scalar()
42+
{
43+
Vector4 result = default;
44+
for (int i = 0; i < this.backdrop.Length; i++)
45+
{
46+
result = PorterDuffFunctions.NormalSrcOver(this.backdrop[i], this.source[i], .5F);
47+
}
48+
49+
return result;
50+
}
51+
52+
[Benchmark(Description = "Avx")]
53+
public Vector256<float> OverlayValueFunction_Avx()
54+
{
55+
ref Vector256<float> backdrop = ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference<Vector4>(this.backdrop));
56+
ref Vector256<float> source = ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference<Vector4>(this.backdrop));
57+
58+
Vector256<float> result = default;
59+
Vector256<float> opacity = Vector256.Create(.5F);
60+
int count = this.backdrop.Length / 2;
61+
for (int i = 0; i < count; i++)
62+
{
63+
result = PorterDuffFunctions.NormalSrcOver(Unsafe.Add(ref backdrop, i), Unsafe.Add(ref source, i), opacity);
64+
}
65+
66+
return result;
67+
}
68+
}

0 commit comments

Comments
 (0)