|
|
|
@ -1,4 +1,7 @@ |
|
|
|
using System; |
|
|
|
// Copyright (c) Six Labors and contributors.
|
|
|
|
// Licensed under the Apache License, Version 2.0.
|
|
|
|
|
|
|
|
using System; |
|
|
|
using System.Numerics; |
|
|
|
using System.Runtime.CompilerServices; |
|
|
|
|
|
|
|
@ -6,6 +9,7 @@ using BenchmarkDotNet.Attributes; |
|
|
|
|
|
|
|
using SixLabors.ImageSharp.Formats.Jpeg.Components; |
|
|
|
using SixLabors.ImageSharp.Memory; |
|
|
|
// ReSharper disable InconsistentNaming
|
|
|
|
|
|
|
|
namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations |
|
|
|
{ |
|
|
|
@ -22,7 +26,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations |
|
|
|
{ |
|
|
|
if (!SimdUtils.IsAvx2CompatibleArchitecture) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("Block8x8F_CopyTo1x1 is invalid on platforms without AVX2 support."); |
|
|
|
throw new InvalidOperationException("Benchmark Block8x8F_CopyTo1x1 is invalid on platforms without AVX2 support."); |
|
|
|
} |
|
|
|
|
|
|
|
this.buffer = Configuration.Default.MemoryAllocator.Allocate2D<float>(1000, 500); |
|
|
|
@ -58,7 +62,17 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations |
|
|
|
public void UseVector8() |
|
|
|
{ |
|
|
|
ref Block8x8F s = ref this.block; |
|
|
|
ref Vector<float> d = ref Unsafe.As<float, Vector<float>>(ref this.destArea.GetReferenceToOrigin()); |
|
|
|
ref float origin = ref this.destArea.GetReferenceToOrigin(); |
|
|
|
int stride = this.destArea.Stride; |
|
|
|
|
|
|
|
ref Vector<float> d0 = ref Unsafe.As<float, Vector<float>>(ref origin); |
|
|
|
ref Vector<float> d1 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride)); |
|
|
|
ref Vector<float> d2 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 2)); |
|
|
|
ref Vector<float> d3 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 3)); |
|
|
|
ref Vector<float> d4 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 4)); |
|
|
|
ref Vector<float> d5 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 5)); |
|
|
|
ref Vector<float> d6 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 6)); |
|
|
|
ref Vector<float> d7 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 7)); |
|
|
|
|
|
|
|
Vector<float> row0 = Unsafe.As<Vector4, Vector<float>>(ref s.V0L); |
|
|
|
Vector<float> row1 = Unsafe.As<Vector4, Vector<float>>(ref s.V1L); |
|
|
|
@ -69,14 +83,51 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations |
|
|
|
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; |
|
|
|
d0 = row0; |
|
|
|
d1 = row1; |
|
|
|
d2 = row2; |
|
|
|
d3 = row3; |
|
|
|
d4 = row4; |
|
|
|
d5 = row5; |
|
|
|
d6 = row6; |
|
|
|
d7 = row7; |
|
|
|
} |
|
|
|
|
|
|
|
[Benchmark] |
|
|
|
public void UseVector8_V2() |
|
|
|
{ |
|
|
|
ref Block8x8F s = ref this.block; |
|
|
|
ref float origin = ref this.destArea.GetReferenceToOrigin(); |
|
|
|
int stride = this.destArea.Stride; |
|
|
|
|
|
|
|
ref Vector<float> d0 = ref Unsafe.As<float, Vector<float>>(ref origin); |
|
|
|
ref Vector<float> d1 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride)); |
|
|
|
ref Vector<float> d2 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 2)); |
|
|
|
ref Vector<float> d3 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 3)); |
|
|
|
ref Vector<float> d4 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 4)); |
|
|
|
ref Vector<float> d5 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 5)); |
|
|
|
ref Vector<float> d6 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 6)); |
|
|
|
ref Vector<float> d7 = ref Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref origin, stride * 7)); |
|
|
|
|
|
|
|
d0 = Unsafe.As<Vector4, Vector<float>>(ref s.V0L); |
|
|
|
d1 = Unsafe.As<Vector4, Vector<float>>(ref s.V1L); |
|
|
|
d2 = Unsafe.As<Vector4, Vector<float>>(ref s.V2L); |
|
|
|
d3 = Unsafe.As<Vector4, Vector<float>>(ref s.V3L); |
|
|
|
d4 = Unsafe.As<Vector4, Vector<float>>(ref s.V4L); |
|
|
|
d5 = Unsafe.As<Vector4, Vector<float>>(ref s.V5L); |
|
|
|
d6 = Unsafe.As<Vector4, Vector<float>>(ref s.V6L); |
|
|
|
d7 = Unsafe.As<Vector4, Vector<float>>(ref s.V7L); |
|
|
|
} |
|
|
|
|
|
|
|
// RESULTS:
|
|
|
|
//
|
|
|
|
// Method | Mean | Error | StdDev | Scaled |
|
|
|
|
// -------------- |---------:|----------:|----------:|-------:|
|
|
|
|
// Original | 22.53 ns | 0.1660 ns | 0.1553 ns | 1.00 |
|
|
|
|
// UseVector8 | 21.59 ns | 0.3079 ns | 0.2571 ns | 0.96 |
|
|
|
|
// UseVector8_V2 | 22.57 ns | 0.1699 ns | 0.1506 ns | 1.00 |
|
|
|
|
//
|
|
|
|
// Conclusion:
|
|
|
|
// Doesn't worth to bother with this
|
|
|
|
} |
|
|
|
} |