mirror of https://github.com/SixLabors/ImageSharp
3 changed files with 190 additions and 38 deletions
@ -0,0 +1,82 @@ |
|||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
using BenchmarkDotNet.Attributes; |
||||
|
|
||||
|
using SixLabors.ImageSharp.Formats.Jpeg.Components; |
||||
|
using SixLabors.ImageSharp.Memory; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations |
||||
|
{ |
||||
|
public class Block8x8F_CopyTo1x1 |
||||
|
{ |
||||
|
private Block8x8F block; |
||||
|
|
||||
|
private Buffer2D<float> buffer; |
||||
|
|
||||
|
private BufferArea<float> destArea; |
||||
|
|
||||
|
[GlobalSetup] |
||||
|
public void Setup() |
||||
|
{ |
||||
|
if (!SimdUtils.IsAvx2CompatibleArchitecture) |
||||
|
{ |
||||
|
throw new InvalidOperationException("Block8x8F_CopyTo1x1 is invalid on platforms without AVX2 support."); |
||||
|
} |
||||
|
|
||||
|
this.buffer = Configuration.Default.MemoryAllocator.Allocate2D<float>(1000, 500); |
||||
|
this.destArea = this.buffer.GetArea(200, 100, 64, 64); |
||||
|
} |
||||
|
|
||||
|
[Benchmark(Baseline = true)] |
||||
|
public void Original() |
||||
|
{ |
||||
|
ref byte selfBase = ref Unsafe.As<Block8x8F, byte>(ref this.block); |
||||
|
ref byte destBase = ref Unsafe.As<float, byte>(ref this.destArea.GetReferenceToOrigin()); |
||||
|
int destStride = this.destArea.Stride * sizeof(float); |
||||
|
|
||||
|
CopyRowImpl(ref selfBase, ref destBase, destStride, 0); |
||||
|
CopyRowImpl(ref selfBase, ref destBase, destStride, 1); |
||||
|
CopyRowImpl(ref selfBase, ref destBase, destStride, 2); |
||||
|
CopyRowImpl(ref selfBase, ref destBase, destStride, 3); |
||||
|
CopyRowImpl(ref selfBase, ref destBase, destStride, 4); |
||||
|
CopyRowImpl(ref selfBase, ref destBase, destStride, 5); |
||||
|
CopyRowImpl(ref selfBase, ref destBase, destStride, 6); |
||||
|
CopyRowImpl(ref selfBase, ref destBase, destStride, 7); |
||||
|
} |
||||
|
|
||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
|
private static void CopyRowImpl(ref byte selfBase, ref byte destBase, int destStride, int row) |
||||
|
{ |
||||
|
ref byte s = ref Unsafe.Add(ref selfBase, row * 8 * sizeof(float)); |
||||
|
ref byte d = ref Unsafe.Add(ref destBase, row * destStride); |
||||
|
Unsafe.CopyBlock(ref d, ref s, 8 * sizeof(float)); |
||||
|
} |
||||
|
|
||||
|
[Benchmark] |
||||
|
public void UseVector8() |
||||
|
{ |
||||
|
ref Block8x8F s = ref this.block; |
||||
|
ref Vector<float> d = ref Unsafe.As<float, Vector<float>>(ref this.destArea.GetReferenceToOrigin()); |
||||
|
|
||||
|
Vector<float> row0 = Unsafe.As<Vector4, Vector<float>>(ref s.V0L); |
||||
|
Vector<float> row1 = Unsafe.As<Vector4, Vector<float>>(ref s.V1L); |
||||
|
Vector<float> row2 = Unsafe.As<Vector4, Vector<float>>(ref s.V2L); |
||||
|
Vector<float> row3 = Unsafe.As<Vector4, Vector<float>>(ref s.V3L); |
||||
|
Vector<float> row4 = Unsafe.As<Vector4, Vector<float>>(ref s.V4L); |
||||
|
Vector<float> row5 = Unsafe.As<Vector4, Vector<float>>(ref s.V5L); |
||||
|
Vector<float> row6 = Unsafe.As<Vector4, Vector<float>>(ref s.V6L); |
||||
|
Vector<float> row7 = Unsafe.As<Vector4, Vector<float>>(ref s.V7L); |
||||
|
|
||||
|
d = row0; |
||||
|
Unsafe.Add(ref d, 1) = row1; |
||||
|
Unsafe.Add(ref d, 2) = row2; |
||||
|
Unsafe.Add(ref d, 3) = row3; |
||||
|
Unsafe.Add(ref d, 4) = row4; |
||||
|
Unsafe.Add(ref d, 5) = row5; |
||||
|
Unsafe.Add(ref d, 6) = row6; |
||||
|
Unsafe.Add(ref d, 7) = row7; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue