Use field-based exponent tracking for steppers
This commit is contained in:
1 parent
d20362a2fc
commit
557bc5d06f
2 files changed
+37
-36
No files matched your search
@@ -10,7 +10,7 @@ internal struct ExponentRemainderStepperCpu
|
||||
private readonly ulong _modulus;
|
||||
private readonly ulong _nPrime;
|
||||
private readonly ulong _montgomeryOne;
|
||||
private ulong _previousExponent;
|
||||
public ulong PreviousExponent;
|
||||
private ulong _currentMontgomery;
|
||||
|
||||
public ExponentRemainderStepperCpu(in MontgomeryDivisorData divisor)
|
||||
@@ -19,12 +19,10 @@ internal struct ExponentRemainderStepperCpu
|
||||
_modulus = divisor.Modulus;
|
||||
_nPrime = divisor.NPrime;
|
||||
_montgomeryOne = divisor.MontgomeryOne;
|
||||
_previousExponent = 0UL;
|
||||
PreviousExponent = 0UL;
|
||||
_currentMontgomery = divisor.MontgomeryOne;
|
||||
}
|
||||
|
||||
public ulong PreviousExponent => _previousExponent;
|
||||
|
||||
public bool MatchesDivisor(in MontgomeryDivisorData divisor)
|
||||
{
|
||||
return _modulus == divisor.Modulus && _nPrime == divisor.NPrime && _montgomeryOne == divisor.MontgomeryOne;
|
||||
@@ -36,7 +34,7 @@ internal struct ExponentRemainderStepperCpu
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
_previousExponent = 0UL;
|
||||
PreviousExponent = 0UL;
|
||||
_currentMontgomery = _montgomeryOne;
|
||||
}
|
||||
|
||||
@@ -71,13 +69,13 @@ internal struct ExponentRemainderStepperCpu
|
||||
/// <returns>The canonical residue produced by <c>2^exponent mod divisor</c>.</returns>
|
||||
public ulong ComputeNextCpu(ulong exponent)
|
||||
{
|
||||
ulong delta = exponent - _previousExponent;
|
||||
ulong delta = exponent - PreviousExponent;
|
||||
// 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.
|
||||
ulong multiplier = delta.Pow2MontgomeryModWindowedCpu(_divisor, keepMontgomery: true);
|
||||
_currentMontgomery = _currentMontgomery.MontgomeryMultiply(multiplier, _modulus, _nPrime);
|
||||
_previousExponent = exponent;
|
||||
PreviousExponent = exponent;
|
||||
return ReduceCurrent();
|
||||
}
|
||||
|
||||
@@ -90,12 +88,12 @@ internal struct ExponentRemainderStepperCpu
|
||||
/// <returns><see langword="true"/> when the canonical residue equals one.</returns>
|
||||
public bool ComputeNextIsUnity(ulong exponent)
|
||||
{
|
||||
ulong delta = exponent - _previousExponent;
|
||||
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.
|
||||
ulong multiplier = delta.Pow2MontgomeryModWindowedCpu(_divisor, keepMontgomery: true);
|
||||
_currentMontgomery = _currentMontgomery.MontgomeryMultiply(multiplier, _modulus, _nPrime);
|
||||
_previousExponent = exponent;
|
||||
PreviousExponent = exponent;
|
||||
return _currentMontgomery == _montgomeryOne;
|
||||
}
|
||||
|
||||
@@ -110,7 +108,7 @@ internal struct ExponentRemainderStepperCpu
|
||||
public bool TryInitializeFromMontgomeryResult(ulong exponent, ulong montgomeryResult, out bool isUnity)
|
||||
{
|
||||
_currentMontgomery = montgomeryResult;
|
||||
_previousExponent = exponent;
|
||||
PreviousExponent = exponent;
|
||||
isUnity = _currentMontgomery == _montgomeryOne;
|
||||
return true;
|
||||
}
|
||||
@@ -129,7 +127,7 @@ internal struct ExponentRemainderStepperCpu
|
||||
// of relying on the caller-provided delta so incremental scans remain in sync with the snapshot
|
||||
// without computing additional cycles or mutating cache state.
|
||||
_currentMontgomery = _currentMontgomery.MontgomeryMultiply(montgomeryDelta, _modulus, _nPrime);
|
||||
_previousExponent = exponent;
|
||||
PreviousExponent = exponent;
|
||||
isUnity = _currentMontgomery == _montgomeryOne;
|
||||
return true;
|
||||
}
|
||||
@@ -137,7 +135,7 @@ internal struct ExponentRemainderStepperCpu
|
||||
private void InitializeCpuState(ulong exponent)
|
||||
{
|
||||
_currentMontgomery = exponent.Pow2MontgomeryModWindowedCpu(_divisor, keepMontgomery: true);
|
||||
_previousExponent = exponent;
|
||||
PreviousExponent = exponent;
|
||||
}
|
||||
|
||||
private ulong ReduceCurrent() => _currentMontgomery.MontgomeryMultiply(1UL, _modulus, _nPrime);
|
||||
|
||||
Reference in new issue
Block a user