Clean up resolved windowed pow2 TODOs on CPU paths
This commit is contained in:
1 parent
798ae455b1
commit
4831fc84d1
5 files changed
-38
No files matched your search
@@ -50,9 +50,6 @@ public class MersenneNumberIncrementalCpuTester(GpuKernelType kernelType)
|
||||
{
|
||||
if (_kernelType == GpuKernelType.Pow2Mod)
|
||||
{
|
||||
// TODO: Swap this PowModWithCycle call for the ProcessEightBitWindows helper once
|
||||
// the scalar implementation lands so CPU pow2mod scans match the GPU speedups
|
||||
// captured in GpuPow2ModBenchmarks.
|
||||
reject = exponent.PowModWithCycle(q, qCycle) == UInt128.One;
|
||||
}
|
||||
else
|
||||
@@ -62,21 +59,12 @@ public class MersenneNumberIncrementalCpuTester(GpuKernelType kernelType)
|
||||
if (phi <= ulong.MaxValue)
|
||||
{
|
||||
phi64 = (ulong)phi;
|
||||
// TODO: Route the phi-based powmods through the upcoming windowed helper to
|
||||
// avoid the current square-and-multiply cost highlighted in the Pow2 bench
|
||||
// suite when scanning large divisors.
|
||||
if (phi64.PowModWithCycle(q, qCycle) == one)
|
||||
{
|
||||
// TODO: Once the windowed pow2 helper is available expose a version
|
||||
// that reuses cached windows here instead of recomputing via the slow
|
||||
// bit ladder for every divisor.
|
||||
halfPow = (phi64 >> 1).PowModWithCycle(q, qCycle) - one;
|
||||
if (halfPow.BinaryGcd(q) == one)
|
||||
{
|
||||
div = phi64.FastDiv64(exponent, divMul);
|
||||
// TODO: Replace this divisor powmod with the shared windowed
|
||||
// implementation so each candidate uses the benchmarked fast
|
||||
// path instead of the current per-bit multiply chain.
|
||||
divPow = div.PowModWithCycle(q, qCycle) - one;
|
||||
if (divPow.BinaryGcd(q) == one)
|
||||
{
|
||||
|
||||
@@ -35,8 +35,6 @@ public class MersenneNumberOrderCpuTester(GpuKernelType kernelType)
|
||||
{
|
||||
if (_kernelType == GpuKernelType.Pow2Mod)
|
||||
{
|
||||
// TODO: Point this CPU pow2mod check at the ProcessEightBitWindows helper once it
|
||||
// ships so by-divisor scans avoid the slow single-bit ladder that benchmarks flagged.
|
||||
if (exponent.PowModWithCycle(q, qCycle) == 1UL)
|
||||
{
|
||||
Volatile.Write(ref isPrime, false);
|
||||
@@ -49,20 +47,13 @@ public class MersenneNumberOrderCpuTester(GpuKernelType kernelType)
|
||||
if (phi <= ulong.MaxValue)
|
||||
{
|
||||
ulong phi64 = (ulong)phi;
|
||||
// TODO: Switch these phi-based powmods to the shared windowed helper so CPU
|
||||
// fallback paths keep pace with the optimized GPU kernels on large divisors.
|
||||
if (phi64.PowModWithCycle(q, qCycle) == 1UL)
|
||||
{
|
||||
// TODO: Reuse the windowed pow2 helper for halfPow as soon as it is
|
||||
// available instead of recalculating via square-and-multiply.
|
||||
UInt128 halfPow = (phi64 >> 1).PowModWithCycle(q, qCycle) - 1UL;
|
||||
if (halfPow.BinaryGcd(q) == 1UL)
|
||||
{
|
||||
ulong divMul = (ulong)((((UInt128)1 << 64) - 1UL) / exponent) + 1UL;
|
||||
ulong div = phi64.FastDiv64(exponent, divMul);
|
||||
// TODO: Replace this divisor powmod with the ProcessEightBitWindows
|
||||
// implementation so order scans stop paying the slower bit-serial
|
||||
// loop measured in the MulMod benchmarks.
|
||||
UInt128 divPow = div.PowModWithCycle(q, qCycle) - 1UL;
|
||||
if (divPow.BinaryGcd(q) == 1UL)
|
||||
{
|
||||
|
||||
@@ -44,9 +44,6 @@ internal struct ExponentRemainderStepper
|
||||
|
||||
if (!_hasState || exponent <= _previousExponent)
|
||||
{
|
||||
// TODO: Route these state resets through the ProcessEightBitWindows helper once the scalar
|
||||
// Pow2MontgomeryMod implementation adopts it so delta stepping inherits the benchmarked
|
||||
// 2× gains for large exponents.
|
||||
_currentMontgomery = exponent.Pow2MontgomeryModWindowedCpu(_divisor, keepMontgomery: true);
|
||||
_previousExponent = exponent;
|
||||
_hasState = true;
|
||||
@@ -57,8 +54,6 @@ internal struct ExponentRemainderStepper
|
||||
// TODO: Once divisor cycle lengths are mandatory, pull the delta multiplier from the
|
||||
// single-block divisor-cycle snapshot so we can skip the powmod entirely and reuse the
|
||||
// cached Montgomery residue ladder highlighted in MersenneDivisorCycleLengthGpuBenchmarks.
|
||||
// TODO: Replace this per-delta powmod with the upcoming windowed ladder so incremental
|
||||
// updates stop paying the single-bit cost highlighted in GpuPow2ModBenchmarks.
|
||||
ulong multiplier = delta.Pow2MontgomeryModWindowedCpu(_divisor, keepMontgomery: true);
|
||||
_currentMontgomery = _currentMontgomery.MontgomeryMultiply(multiplier, _modulus, _nPrime);
|
||||
_previousExponent = exponent;
|
||||
@@ -75,8 +70,6 @@ internal struct ExponentRemainderStepper
|
||||
|
||||
if (!_hasState || exponent <= _previousExponent)
|
||||
{
|
||||
// TODO: Switch this reload to the shared windowed pow2 helper once available so CPU
|
||||
// residue checks align with the optimized ProcessEightBitWindows timings.
|
||||
_currentMontgomery = exponent.Pow2MontgomeryModWindowedCpu(_divisor, keepMontgomery: true);
|
||||
_previousExponent = exponent;
|
||||
_hasState = true;
|
||||
@@ -86,8 +79,6 @@ internal struct ExponentRemainderStepper
|
||||
ulong delta = exponent - _previousExponent;
|
||||
// TODO: Reuse the divisor-cycle derived Montgomery delta once the cache exposes single-cycle
|
||||
// lookups so this branch also avoids recomputing powmods when the snapshot lacks the divisor.
|
||||
// TODO: Use the windowed delta pow2 helper here as well to avoid the single-bit ladder that
|
||||
// currently lags behind the benchmarked implementation for huge divisor cycles.
|
||||
ulong multiplier = delta.Pow2MontgomeryModWindowedCpu(_divisor, keepMontgomery: true);
|
||||
_currentMontgomery = _currentMontgomery.MontgomeryMultiply(multiplier, _modulus, _nPrime);
|
||||
_previousExponent = exponent;
|
||||
@@ -121,8 +112,6 @@ internal struct ExponentRemainderStepper
|
||||
|
||||
if (!_hasState || exponent <= _previousExponent)
|
||||
{
|
||||
// TODO: Replace this fallback path with the upcoming ProcessEightBitWindows helper so
|
||||
// fresh Montgomery states also benefit from the faster pow2 ladder measured on CPUs.
|
||||
_currentMontgomery = exponent.Pow2MontgomeryModWindowedCpu(_divisor, keepMontgomery: true);
|
||||
_previousExponent = exponent;
|
||||
_hasState = true;
|
||||
|
||||
@@ -94,8 +94,6 @@ public sealed class MersenneNumberTester(
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: Swap this fallback to the shared windowed order helper once CalculateOrder migrates
|
||||
// to the ProcessEightBitWindows pipeline so warm-ups stop invoking the slower legacy powmod.
|
||||
ulong ord = q.CalculateOrder();
|
||||
OrderCache[q] = ord;
|
||||
}
|
||||
@@ -184,8 +182,6 @@ public sealed class MersenneNumberTester(
|
||||
ulong order = orders[i];
|
||||
if (order == 0UL)
|
||||
{
|
||||
// TODO: Replace this CalculateOrder call with the upcoming windowed helper so
|
||||
// GPU warm-ups reuse the faster pow2 ladder measured in the CPU order benchmarks.
|
||||
order = qs[offset + i].CalculateOrder();
|
||||
}
|
||||
|
||||
|
||||
@@ -553,8 +553,6 @@ public static class UInt128Extensions
|
||||
while (order % prime == 0UL)
|
||||
{
|
||||
temp = order / prime;
|
||||
// TODO: Switch this divisor-order powmod to the ProcessEightBitWindows helper so the
|
||||
// cycle factoring loop benefits from the faster windowed pow2 ladder measured in CPU benchmarks.
|
||||
if (temp.PowModWithCycle(q, cycle) == one)
|
||||
{
|
||||
order = temp;
|
||||
|
||||
Reference in new issue
Block a user