Browse Source

Refactored code to use new Octet<T> type

af/qhack03
Sergio Pedri 6 years ago
parent
commit
d7b9b666c1
  1. 30
      src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs
  2. 5
      src/ImageSharp/Common/Tuples/Octet{T}.cs
  3. 10
      tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs
  4. 4
      tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs

30
src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs

@ -94,17 +94,17 @@ namespace SixLabors.ImageSharp
var magicInt = new Vector<uint>(1191182336); // reinterpreted value of 32768.0f
var mask = new Vector<uint>(255);
ref Octet.OfByte sourceBase = ref Unsafe.As<byte, Octet.OfByte>(ref MemoryMarshal.GetReference(source));
ref Octet.OfUInt32 destBaseAsWideOctet = ref Unsafe.As<float, Octet.OfUInt32>(ref MemoryMarshal.GetReference(dest));
ref Octet<byte> sourceBase = ref Unsafe.As<byte, Octet<byte>>(ref MemoryMarshal.GetReference(source));
ref Octet<uint> destBaseAsWideOctet = ref Unsafe.As<float, Octet<uint>>(ref MemoryMarshal.GetReference(dest));
ref Vector<float> destBaseAsFloat = ref Unsafe.As<Octet.OfUInt32, Vector<float>>(ref destBaseAsWideOctet);
ref Vector<float> destBaseAsFloat = ref Unsafe.As<Octet<uint>, Vector<float>>(ref destBaseAsWideOctet);
int n = dest.Length / 8;
for (int i = 0; i < n; i++)
{
ref Octet.OfByte s = ref Unsafe.Add(ref sourceBase, i);
ref Octet.OfUInt32 d = ref Unsafe.Add(ref destBaseAsWideOctet, i);
ref Octet<byte> s = ref Unsafe.Add(ref sourceBase, i);
ref Octet<uint> d = ref Unsafe.Add(ref destBaseAsWideOctet, i);
d.LoadFrom(ref s);
}
@ -137,17 +137,17 @@ namespace SixLabors.ImageSharp
}
ref Vector<float> srcBase = ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(source));
ref Octet.OfByte destBase = ref Unsafe.As<byte, Octet.OfByte>(ref MemoryMarshal.GetReference(dest));
ref Octet<byte> destBase = ref Unsafe.As<byte, Octet<byte>>(ref MemoryMarshal.GetReference(dest));
int n = source.Length / 8;
var magick = new Vector<float>(32768.0f);
var scale = new Vector<float>(255f) / new Vector<float>(256f);
// need to copy to a temporary struct, because
// SimdUtils.Octet.OfUInt32 temp = Unsafe.As<Vector<float>, SimdUtils.Octet.OfUInt32>(ref x)
// SimdUtils.Octet<uint> temp = Unsafe.As<Vector<float>, SimdUtils.Octet<uint>>(ref x)
// does not work. TODO: This might be a CoreClr bug, need to ask/report
var temp = default(Octet.OfUInt32);
ref Vector<float> tempRef = ref Unsafe.As<Octet.OfUInt32, Vector<float>>(ref temp);
var temp = default(Octet<uint>);
ref Vector<float> tempRef = ref Unsafe.As<Octet<uint>, Vector<float>>(ref temp);
for (int i = 0; i < n; i++)
{
@ -161,7 +161,7 @@ namespace SixLabors.ImageSharp
x = (x * scale) + magick;
tempRef = x;
ref Octet.OfByte d = ref Unsafe.Add(ref destBase, i);
ref Octet<byte> d = ref Unsafe.Add(ref destBase, i);
d.LoadFrom(ref temp);
}
}
@ -186,17 +186,17 @@ namespace SixLabors.ImageSharp
}
ref Vector<float> srcBase = ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(source));
ref Octet.OfByte destBase = ref Unsafe.As<byte, Octet.OfByte>(ref MemoryMarshal.GetReference(dest));
ref Octet<byte> destBase = ref Unsafe.As<byte, Octet<byte>>(ref MemoryMarshal.GetReference(dest));
int n = source.Length / 8;
var magick = new Vector<float>(32768.0f);
var scale = new Vector<float>(255f) / new Vector<float>(256f);
// need to copy to a temporary struct, because
// SimdUtils.Octet.OfUInt32 temp = Unsafe.As<Vector<float>, SimdUtils.Octet.OfUInt32>(ref x)
// SimdUtils.Octet<uint> temp = Unsafe.As<Vector<float>, SimdUtils.Octet<uint>>(ref x)
// does not work. TODO: This might be a CoreClr bug, need to ask/report
var temp = default(Octet.OfUInt32);
ref Vector<float> tempRef = ref Unsafe.As<Octet.OfUInt32, Vector<float>>(ref temp);
var temp = default(Octet<uint>);
ref Vector<float> tempRef = ref Unsafe.As<Octet<uint>, Vector<float>>(ref temp);
for (int i = 0; i < n; i++)
{
@ -207,7 +207,7 @@ namespace SixLabors.ImageSharp
x = (x * scale) + magick;
tempRef = x;
ref Octet.OfByte d = ref Unsafe.Add(ref destBase, i);
ref Octet<byte> d = ref Unsafe.Add(ref destBase, i);
d.LoadFrom(ref temp);
}
}

5
src/ImageSharp/Common/Tuples/Octet{T}.cs

@ -3,9 +3,8 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Tuples;
namespace SixLabors.ImageSharp.Common.Tuples
namespace SixLabors.ImageSharp.Tuples
{
/// <summary>
/// Contains 8 element value tuples of various types.
@ -26,7 +25,7 @@ namespace SixLabors.ImageSharp.Common.Tuples
/// <inheritdoc/>
public override readonly string ToString()
{
return $"{nameof(Octet)}<{typeof(T)}>({this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7})";
return $"Octet<{typeof(T)}>({this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7})";
}
}

10
tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs

@ -233,8 +233,8 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion
// [Benchmark]
public void Bitops_Simd()
{
ref Octet.OfUInt32 sBase = ref Unsafe.As<Rgba32, Octet.OfUInt32>(ref this.source[0]);
ref Octet.OfUInt32 dBase = ref Unsafe.As<Bgra32, Octet.OfUInt32>(ref this.dest[0]);
ref Octet<uint> sBase = ref Unsafe.As<Rgba32, Octet<uint>>(ref this.source[0]);
ref Octet<uint> dBase = ref Unsafe.As<Bgra32, Octet<uint>>(ref this.dest[0]);
for (int i = 0; i < this.Count / 8; i++)
{
@ -257,9 +257,9 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion
#pragma warning restore SA1132 // Do not combine fields
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void BitopsSimdImpl(ref Octet.OfUInt32 s, ref Octet.OfUInt32 d)
private static void BitopsSimdImpl(ref Octet<uint> s, ref Octet<uint> d)
{
Vector<uint> sVec = Unsafe.As<Octet.OfUInt32, Vector<uint>>(ref s);
Vector<uint> sVec = Unsafe.As<Octet<uint>, Vector<uint>>(ref s);
var aMask = new Vector<uint>(0xFF00FF00);
var bMask = new Vector<uint>(0x00FF00FF);
@ -282,7 +282,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion
Vector<uint> cc = Unsafe.As<C, Vector<uint>>(ref c);
Vector<uint> dd = aa + cc;
d = Unsafe.As<Vector<uint>, Octet.OfUInt32>(ref dd);
d = Unsafe.As<Vector<uint>, Octet<uint>>(ref dd);
}
// [Benchmark]

4
tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs

@ -31,8 +31,8 @@ namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization
{
const int N = Count / 8;
ref Octet.OfByte sBase = ref Unsafe.As<byte, Octet.OfByte>(ref this.source[0]);
ref Octet.OfUInt32 dBase = ref Unsafe.As<uint, Octet.OfUInt32>(ref this.dest[0]);
ref Octet<byte> sBase = ref Unsafe.As<byte, Octet<byte>>(ref this.source[0]);
ref Octet<uint> dBase = ref Unsafe.As<uint, Octet<uint>>(ref this.dest[0]);
for (int i = 0; i < N; i++)
{

Loading…
Cancel
Save