Browse Source

run default implementation for small buffers

pull/751/head
Anton Firszov 7 years ago
parent
commit
0fc01d75f4
  1. 63
      src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
  2. 28
      tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs

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

@ -36,15 +36,7 @@ namespace SixLabors.ImageSharp.PixelFormats
Guard.NotNull(configuration, nameof(configuration));
Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels));
ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors);
ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels);
for (int i = 0; i < sourceVectors.Length; i++)
{
ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i);
ref TPixel dp = ref Unsafe.Add(ref destRef, i);
dp.FromVector4(sp);
}
FromVector4DefaultImpl(sourceVectors, destPixels);
}
/// <summary>
@ -61,15 +53,7 @@ namespace SixLabors.ImageSharp.PixelFormats
Guard.NotNull(configuration, nameof(configuration));
Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors));
ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourcePixels);
ref Vector4 destRef = ref MemoryMarshal.GetReference(destVectors);
for (int i = 0; i < sourcePixels.Length; i++)
{
ref TPixel sp = ref Unsafe.Add(ref sourceRef, i);
ref Vector4 dp = ref Unsafe.Add(ref destRef, i);
dp = sp.ToVector4();
}
ToVector4DefaultImpl(sourcePixels, destVectors);
}
/// <summary>
@ -135,6 +119,7 @@ namespace SixLabors.ImageSharp.PixelFormats
Span<TDestinationPixel> destinationColors)
where TDestinationPixel : struct, IPixel<TDestinationPixel>
{
Guard.NotNull(configuration, nameof(configuration));
Guard.DestinationShouldNotBeTooShort(sourceColors, destinationColors, nameof(destinationColors));
int count = sourceColors.Length;
@ -197,6 +182,13 @@ namespace SixLabors.ImageSharp.PixelFormats
int count = sourcePixels.Length;
// Not worth for small buffers:
if (count < 128)
{
ToVector4DefaultImpl(sourcePixels, destVectors);
return;
}
using (IMemoryOwner<Rgba32> tempBuffer = configuration.MemoryAllocator.Allocate<Rgba32>(count))
{
Span<Rgba32> tempSpan = tempBuffer.Memory.Span;
@ -225,6 +217,13 @@ namespace SixLabors.ImageSharp.PixelFormats
int count = sourceVectors.Length;
// Not worth for small buffers:
if (count < 128)
{
FromVector4DefaultImpl(sourceVectors, destPixels);
return;
}
using (IMemoryOwner<Rgba32> tempBuffer = configuration.MemoryAllocator.Allocate<Rgba32>(count))
{
Span<Rgba32> tempSpan = tempBuffer.Memory.Span;
@ -236,5 +235,33 @@ namespace SixLabors.ImageSharp.PixelFormats
this.FromRgba32(configuration, tempSpan, destPixels);
}
}
[MethodImpl(InliningOptions.ShortMethod)]
private static void FromVector4DefaultImpl(ReadOnlySpan<Vector4> sourceVectors, Span<TPixel> destPixels)
{
ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors);
ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels);
for (int i = 0; i < sourceVectors.Length; i++)
{
ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i);
ref TPixel dp = ref Unsafe.Add(ref destRef, i);
dp.FromVector4(sp);
}
}
[MethodImpl(InliningOptions.ShortMethod)]
private static void ToVector4DefaultImpl(ReadOnlySpan<TPixel> sourcePixels, Span<Vector4> destVectors)
{
ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourcePixels);
ref Vector4 destRef = ref MemoryMarshal.GetReference(destVectors);
for (int i = 0; i < sourcePixels.Length; i++)
{
ref TPixel sp = ref Unsafe.Add(ref sourceRef, i);
ref Vector4 dp = ref Unsafe.Add(ref destRef, i);
dp = sp.ToVector4();
}
}
}
}

28
tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs

@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk
[Params(
64,
//256,
256,
//512,
//1024,
2048)]
@ -58,20 +58,25 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk
d[i] = s[i].ToVector4();
}
}
[Benchmark]
public void PixelOperations_Base()
public void PixelOperations_Specialized()
{
new PixelOperations<TPixel>().ToVector4(
PixelOperations<TPixel>.Instance.ToVector4(
this.Configuration,
this.source.GetSpan(),
this.destination.GetSpan());
}
}
[Benchmark]
public void PixelOperations_Specialized()
[Config(typeof(Config.ShortClr))]
public class ToVector4_Bgra32 : ToVector4<Bgra32>
{
[Benchmark(Baseline = true)]
public void PixelOperations_Base()
{
PixelOperations<TPixel>.Instance.ToVector4(
new PixelOperations<Bgra32>().ToVector4(
this.Configuration,
this.source.GetSpan(),
this.destination.GetSpan());
@ -89,7 +94,16 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk
SimdUtils.FallbackIntrinsics128.BulkConvertByteToNormalizedFloat(sBytes, dFloats);
}
[Benchmark]
public void PixelOperations_Base()
{
new PixelOperations<Rgba32>().ToVector4(
this.Configuration,
this.source.GetSpan(),
this.destination.GetSpan());
}
[Benchmark(Baseline = true)]
public void BasicIntrinsics256()
{

Loading…
Cancel
Save