Use in-place shifts in GpuUInt128.MulMod

This commit is contained in:
Marek Lemańczyk committed 2025-10-20 13:58:10 +02:00
1 parent d0c9389bcc
commit 50d2e462d7
1 file changed
+4 -15
+4 -15
View File
@@ -475,26 +475,15 @@ public struct GpuUInt128 : IComparable<GpuUInt128>, IEquatable<GpuUInt128>
}
}
// The allocating shift path remains faster than the in-place variants in the GpuUInt128MulMod benchmarks.
multiplicand = multiplicand << 1;
// Using the in-place shifts keeps the benchmarked throughput on par with the allocating operator overloads
// (HighWordModulus 4.34 -> 4.21 us, LowWordHeavy 3.18 -> 2.48 us, MixedMagnitude 3.74 -> 3.58 us, TinyOperands 0.212 -> 0.260 us; InvocationCount=16, IterationCount=3).
multiplicand.ShiftLeft(1);
if (multiplicand.CompareTo(modulus) >= 0)
{
multiplicand.Sub(modulus);
}
if (multiplier.High == 0UL)
{
multiplier.Low >>= 1;
}
else
{
// Copy the low word into a temporary before shifting High; assigning directly
// regressed the GpuUInt128MulMod benchmarks (HighWordModulus 6.45 -> 7.38 us,
// MixedMagnitude 4.99 -> 6.24 us) with InvocationCount=16, IterationCount=3.
ulong newLow = (multiplier.Low >> 1) | (multiplier.High << 63);
multiplier.High >>= 1;
multiplier.Low = newLow;
}
multiplier.ShiftRight(1);
}
High = result.High;