From f1517d2126d00579fe93f89760155b7f9a60bf39 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 28 Mar 2017 00:59:14 +0200 Subject: [PATCH 1/2] fixing #146 --- src/ImageSharp/Colors/Color.BulkOperations.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/Colors/Color.BulkOperations.cs b/src/ImageSharp/Colors/Color.BulkOperations.cs index 039fafced6..7d3b12ea0b 100644 --- a/src/ImageSharp/Colors/Color.BulkOperations.cs +++ b/src/ImageSharp/Colors/Color.BulkOperations.cs @@ -42,6 +42,12 @@ namespace ImageSharp BufferSpan destVectors, int count) { + if (!Vector.IsHardwareAccelerated) + { + throw new InvalidOperationException( + "Color.BulkOperations.ToVector4SimdAligned() should not be called when Vector.IsHardwareAccelerated == false!"); + } + int vecSize = Vector.Count; DebugGuard.IsTrue( @@ -92,7 +98,7 @@ namespace ImageSharp /// internal override void ToVector4(BufferSpan sourceColors, BufferSpan destVectors, int count) { - if (count < 256) + if (count < 256 || !Vector.IsHardwareAccelerated) { // Doesn't worth to bother with SIMD: base.ToVector4(sourceColors, destVectors, count); From 4231a109953009ea162df2e5e9c9440b61b58573 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 28 Mar 2017 02:26:18 +0200 Subject: [PATCH 2/2] PackFromVector4ReferenceVsPointer benchmark --- .../Bulk/PackFromVector4ReferenceVsPointer.cs | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs new file mode 100644 index 0000000000..e912ea29f6 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs @@ -0,0 +1,74 @@ +namespace ImageSharp.Benchmarks +{ + using System.Numerics; + using System.Runtime.CompilerServices; + + using BenchmarkDotNet.Attributes; + + using ImageSharp; + + /// + /// Compares two implementation candidates for general BulkPixelOperations.ToVector4(): + /// - One iterating with pointers + /// - One iterating with ref locals + /// + public unsafe class PackFromVector4ReferenceVsPointer + { + private PinnedBuffer destination; + + private PinnedBuffer source; + + [Params(16, 128, 1024)] + public int Count { get; set; } + + [Setup] + public void Setup() + { + this.destination = new PinnedBuffer(this.Count); + this.source = new PinnedBuffer(this.Count * 4); + } + + [Cleanup] + public void Cleanup() + { + this.source.Dispose(); + this.destination.Dispose(); + } + + [Benchmark(Baseline = true)] + public void PackUsingPointers() + { + Vector4* sp = (Vector4*)this.source.Pointer; + byte* dp = (byte*)this.destination.Pointer; + int count = this.Count; + int size = sizeof(ImageSharp.Color); + + for (int i = 0; i < count; i++) + { + Vector4 v = Unsafe.Read(sp); + ImageSharp.Color c = default(ImageSharp.Color); + c.PackFromVector4(v); + Unsafe.Write(dp, c); + + sp++; + dp += size; + } + } + + [Benchmark] + public void PackUsingReferences() + { + ref Vector4 sp = ref this.source.Array[0]; + ref ImageSharp.Color dp = ref this.destination.Array[0]; + int count = this.Count; + + for (int i = 0; i < count; i++) + { + dp.PackFromVector4(sp); + + sp = Unsafe.Add(ref sp, 1); + dp = Unsafe.Add(ref dp, 1); + } + } + } +} \ No newline at end of file