Browse Source

Update ShuffleNative (byte)

pull/2918/head
James Jackson-South 1 year ago
parent
commit
505ecce3fa
  1. 20
      src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
  2. 35
      src/ImageSharp/Common/Helpers/Vector128Utilities.cs
  3. 2
      src/ImageSharp/Common/Helpers/Vector256Utilities.cs
  4. 1
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs

20
src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs

@ -113,7 +113,7 @@ internal static partial class SimdUtils
[ConstantExpected] byte control)
{
if ((Vector512.IsHardwareAccelerated && Vector512_.SupportsShuffleNativeByte) ||
(Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleByte) ||
(Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleNativeByte) ||
(Vector128.IsHardwareAccelerated && Vector128_.SupportsShuffleNativeByte))
{
int remainder = 0;
@ -158,7 +158,7 @@ internal static partial class SimdUtils
ref Span<byte> destination,
[ConstantExpected] byte control)
{
if (Vector128.IsHardwareAccelerated && Vector128_.SupportsShuffleNativeByte && Vector128_.SupportsRightAlign)
if (Vector128.IsHardwareAccelerated && Vector128_.SupportsShuffleNativeByte && Vector128_.SupportsAlignRight)
{
int remainder = source.Length % (Vector128<byte>.Count * 3);
@ -373,7 +373,7 @@ internal static partial class SimdUtils
}
}
}
else if (Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleByte)
else if (Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleNativeByte)
{
Span<byte> temp = stackalloc byte[Vector256<byte>.Count];
Shuffle.MMShuffleSpan(ref temp, control);
@ -445,7 +445,9 @@ internal static partial class SimdUtils
Span<byte> destination,
[ConstantExpected] byte control)
{
if (Vector128.IsHardwareAccelerated && Vector128_.SupportsShuffleNativeByte && Vector128_.SupportsRightAlign)
if (Vector128.IsHardwareAccelerated &&
Vector128_.SupportsShuffleNativeByte &&
Vector128_.SupportsAlignRight)
{
Vector128<byte> maskPad4Nx16 = ShuffleMaskPad4Nx16();
Vector128<byte> maskSlice4Nx16 = ShuffleMaskSlice4Nx16();
@ -505,7 +507,10 @@ internal static partial class SimdUtils
Span<byte> destination,
[ConstantExpected] byte control)
{
if (Vector128.IsHardwareAccelerated && Vector128_.SupportsShuffleNativeByte && Vector128_.SupportsShiftByte)
if (Vector128.IsHardwareAccelerated &&
Vector128_.SupportsShuffleNativeByte &&
Vector128_.SupportsShiftByte &&
Vector128_.SupportsAlignRight)
{
Vector128<byte> maskPad4Nx16 = ShuffleMaskPad4Nx16();
Vector128<byte> fill = Vector128.Create(0xff000000ff000000ul).AsByte();
@ -548,7 +553,10 @@ internal static partial class SimdUtils
Span<byte> destination,
[ConstantExpected] byte control)
{
if (Vector128.IsHardwareAccelerated && Vector128_.SupportsShuffleNativeByte && Vector128_.SupportsShiftByte)
if (Vector128.IsHardwareAccelerated &&
Vector128_.SupportsShuffleNativeByte &&
Vector128_.SupportsShiftByte &&
Vector128_.SupportsAlignRight)
{
Vector128<byte> maskSlice4Nx16 = ShuffleMaskSlice4Nx16();
Vector128<byte> maskE = Vector128_.AlignRight(maskSlice4Nx16, maskSlice4Nx16, 12);

35
src/ImageSharp/Common/Helpers/Vector128Utilities.cs

@ -4,6 +4,7 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.Wasm;
@ -38,13 +39,26 @@ internal static class Vector128_
public static bool SupportsShuffleNativeByte
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Ssse3.IsSupported || AdvSimd.Arm64.IsSupported || PackedSimd.IsSupported;
get
{
if (Vector128.IsHardwareAccelerated)
{
if (RuntimeInformation.ProcessArchitecture is Architecture.X86 or Architecture.X64)
{
return Ssse3.IsSupported;
}
return true;
}
return false;
}
}
/// <summary>
/// Gets a value indicating whether right align operations are supported.
/// </summary>
public static bool SupportsRightAlign
public static bool SupportsAlignRight
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Ssse3.IsSupported || AdvSimd.IsSupported;
@ -91,23 +105,16 @@ internal static class Vector128_
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<byte> ShuffleNative(Vector128<byte> vector, Vector128<byte> indices)
{
// For x64 we use the SSSE3 shuffle intrinsic to avoid additional instructions. 3 vs 1.
if (Ssse3.IsSupported)
{
return Ssse3.Shuffle(vector, indices);
}
if (AdvSimd.Arm64.IsSupported)
{
return AdvSimd.Arm64.VectorTableLookup(vector, indices);
}
if (PackedSimd.IsSupported)
{
return PackedSimd.Swizzle(vector, indices);
}
ThrowUnreachableException();
return default;
// For ARM and WASM, codegen will be optimal.
// We don't throw for x86/x64 so we should never use this method without
// checking for support.
return Vector128.Shuffle(vector, indices);
}
/// <summary>

2
src/ImageSharp/Common/Helpers/Vector256Utilities.cs

@ -33,7 +33,7 @@ internal static class Vector256_
/// <summary>
/// Gets a value indicating whether shuffle byte operations are supported.
/// </summary>
public static bool SupportsShuffleByte
public static bool SupportsShuffleNativeByte
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Avx2.IsSupported;

1
src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs

@ -5,7 +5,6 @@ using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using System.Text;
using SixLabors.ImageSharp.Common.Helpers;

Loading…
Cancel
Save