Skip to content

Commit

Permalink
Optimize XxHash3 on ARM platform (#77881)
Browse files Browse the repository at this point in the history
* Optimize XxHash3 on ARM platform

* Extract code to MultiplyWideningLower

* Update src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHash3.cs

Co-authored-by: Stephen Toub <[email protected]>

Co-authored-by: Stephen Toub <[email protected]>
  • Loading branch information
xoofx and stephentoub authored Nov 5, 2022
1 parent 09c81d8 commit ec26662
Showing 1 changed file with 20 additions and 4 deletions.
24 changes: 20 additions & 4 deletions src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHash3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Runtime.InteropServices;
#if NET7_0_OR_GREATER
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.X86;
#endif

Expand Down Expand Up @@ -896,16 +897,31 @@ private static Vector128<ulong> Accumulate128(Vector128<ulong> accVec, byte* sou
Vector128<uint> sourceKey = sourceVec ^ secret;

// TODO: Figure out how to unwind this shuffle and just use Vector128.Multiply
Vector128<uint> sourceKeyLow = Vector128.Shuffle(sourceKey, Vector128.Create(1u, 0, 3, 0));
Vector128<uint> sourceSwap = Vector128.Shuffle(sourceVec, Vector128.Create(2u, 3, 0, 1));
Vector128<ulong> sum = accVec + sourceSwap.AsUInt64();
Vector128<ulong> product = Sse2.IsSupported ?
Sse2.Multiply(sourceKey, sourceKeyLow) :
(sourceKey & Vector128.Create(~0u, 0u, ~0u, 0u)).AsUInt64() * (sourceKeyLow & Vector128.Create(~0u, 0u, ~0u, 0u)).AsUInt64();

Vector128<ulong> product = MultiplyWideningLower(sourceKey);
accVec = product + sum;
return accVec;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128<ulong> MultiplyWideningLower(Vector128<uint> source)
{
if (AdvSimd.IsSupported)
{
Vector64<uint> sourceLow = Vector128.Shuffle(source, Vector128.Create(0u, 2, 0, 0)).GetLower();
Vector64<uint> sourceHigh = Vector128.Shuffle(source, Vector128.Create(1u, 3, 0, 0)).GetLower();
return AdvSimd.MultiplyWideningLower(sourceLow, sourceHigh);
}
else
{
Vector128<uint> sourceLow = Vector128.Shuffle(source, Vector128.Create(1u, 0, 3, 0));
return Sse2.IsSupported ?
Sse2.Multiply(source, sourceLow) :
(source & Vector128.Create(~0u, 0u, ~0u, 0u)).AsUInt64() * (sourceLow & Vector128.Create(~0u, 0u, ~0u, 0u)).AsUInt64();
}
}
#endif

private static void ScrambleAccumulators(ulong* accumulators, byte* secret)
Expand Down

0 comments on commit ec26662

Please sign in to comment.