Use in-place shifts in GpuUInt128.MulMod
This commit is contained in:
1 parent
d0c9389bcc
commit
50d2e462d7
1 file changed
+4
-15
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user