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 buffer; private BufferArea 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(1000, 500); this.destArea = this.buffer.GetArea(200, 100, 64, 64); } [Benchmark(Baseline = true)] public void Original() { ref byte selfBase = ref Unsafe.As(ref this.block); ref byte destBase = ref Unsafe.As(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 d = ref Unsafe.As>(ref this.destArea.GetReferenceToOrigin()); Vector row0 = Unsafe.As>(ref s.V0L); Vector row1 = Unsafe.As>(ref s.V1L); Vector row2 = Unsafe.As>(ref s.V2L); Vector row3 = Unsafe.As>(ref s.V3L); Vector row4 = Unsafe.As>(ref s.V4L); Vector row5 = Unsafe.As>(ref s.V5L); Vector row6 = Unsafe.As>(ref s.V6L); Vector row7 = Unsafe.As>(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; } } }