Cache divisor cycle suppression scopes
This commit is contained in:
1 parent
e1be80048f
commit
3c926e4909
1 file changed
+91
@@ -61,6 +61,18 @@ internal static partial class PrimeOrderCalculator
|
|||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static Dictionary<ulong, int>? s_partialFactorCounts;
|
private static Dictionary<ulong, int>? s_partialFactorCounts;
|
||||||
|
|
||||||
|
[ThreadStatic]
|
||||||
|
private static ulong s_cachedDivisorCycleModulus;
|
||||||
|
|
||||||
|
[ThreadStatic]
|
||||||
|
private static ulong s_cachedDivisorCycleLength;
|
||||||
|
|
||||||
|
[ThreadStatic]
|
||||||
|
private static bool s_hasCachedDivisorCycle;
|
||||||
|
|
||||||
|
[ThreadStatic]
|
||||||
|
private static int s_divisorCycleSuppressionDepth;
|
||||||
|
|
||||||
private static bool IsGpuHeuristicDevice => s_pow2ModeInitialized && s_deviceMode == PrimeOrderHeuristicDevice.Gpu;
|
private static bool IsGpuHeuristicDevice => s_pow2ModeInitialized && s_deviceMode == PrimeOrderHeuristicDevice.Gpu;
|
||||||
|
|
||||||
private readonly struct Pow2ModeScope
|
private readonly struct Pow2ModeScope
|
||||||
@@ -110,10 +122,45 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsDivisorCycleSuppressed => s_divisorCycleSuppressionDepth > 0;
|
||||||
|
|
||||||
|
private readonly struct DivisorCycleSuppressionScope
|
||||||
|
{
|
||||||
|
private readonly bool _suppress;
|
||||||
|
|
||||||
|
private DivisorCycleSuppressionScope(bool suppress)
|
||||||
|
{
|
||||||
|
_suppress = suppress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DivisorCycleSuppressionScope Suppressed = new(true);
|
||||||
|
|
||||||
|
public static readonly DivisorCycleSuppressionScope Unsuppressed = new(false);
|
||||||
|
|
||||||
|
public void Enter()
|
||||||
|
{
|
||||||
|
if (_suppress)
|
||||||
|
{
|
||||||
|
s_divisorCycleSuppressionDepth++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Exit()
|
||||||
|
{
|
||||||
|
if (_suppress)
|
||||||
|
{
|
||||||
|
s_divisorCycleSuppressionDepth--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Pow2ModeScope UsePow2Mode(PrimeOrderHeuristicDevice device) => new(device);
|
private static Pow2ModeScope UsePow2Mode(PrimeOrderHeuristicDevice device) => new(device);
|
||||||
|
|
||||||
private static DebugLoggingScope UseDebugLogging(bool enabled) => new(enabled);
|
private static DebugLoggingScope UseDebugLogging(bool enabled) => new(enabled);
|
||||||
|
|
||||||
|
private static DivisorCycleSuppressionScope SuppressDivisorCycleUsage(bool suppress) =>
|
||||||
|
suppress ? DivisorCycleSuppressionScope.Suppressed : DivisorCycleSuppressionScope.Unsuppressed;
|
||||||
|
|
||||||
[Conditional("DEBUG")]
|
[Conditional("DEBUG")]
|
||||||
private static void DebugLog(string message)
|
private static void DebugLog(string message)
|
||||||
{
|
{
|
||||||
@@ -186,6 +233,10 @@ internal static partial class PrimeOrderCalculator
|
|||||||
in MontgomeryDivisorData divisorData,
|
in MontgomeryDivisorData divisorData,
|
||||||
ulong phi,
|
ulong phi,
|
||||||
PartialFactorResult phiFactors)
|
PartialFactorResult phiFactors)
|
||||||
|
{
|
||||||
|
var cycleScope = SuppressDivisorCycleUsage(config.Mode == PrimeOrderMode.Heuristic && !IsGpuHeuristicDevice);
|
||||||
|
cycleScope.Enter();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (phiFactors.FullyFactored && TrySpecialMaxCpu(phi, prime, phiFactors, divisorData))
|
if (phiFactors.FullyFactored && TrySpecialMaxCpu(phi, prime, phiFactors, divisorData))
|
||||||
{
|
{
|
||||||
@@ -225,6 +276,11 @@ internal static partial class PrimeOrderCalculator
|
|||||||
orderFactors.Dispose();
|
orderFactors.Dispose();
|
||||||
return candidateOrder;
|
return candidateOrder;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
cycleScope.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static bool TrySpecialMaxCpu(ulong phi, ulong prime, PartialFactorResult factors, in MontgomeryDivisorData divisorData)
|
private static bool TrySpecialMaxCpu(ulong phi, ulong prime, PartialFactorResult factors, in MontgomeryDivisorData divisorData)
|
||||||
{
|
{
|
||||||
@@ -787,6 +843,36 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool TryGetDivisorCycle(ulong prime, in MontgomeryDivisorData divisorData, out ulong cycleLength)
|
||||||
|
{
|
||||||
|
if (prime <= 1UL || IsDivisorCycleSuppressed)
|
||||||
|
{
|
||||||
|
cycleLength = 0UL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_hasCachedDivisorCycle && s_cachedDivisorCycleModulus == prime)
|
||||||
|
{
|
||||||
|
cycleLength = s_cachedDivisorCycleLength;
|
||||||
|
return cycleLength != 0UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
var suppression = SuppressDivisorCycleUsage(true);
|
||||||
|
suppression.Enter();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cycleLength = MersenneDivisorCycles.CalculateCycleLength(prime, divisorData);
|
||||||
|
s_cachedDivisorCycleModulus = prime;
|
||||||
|
s_cachedDivisorCycleLength = cycleLength;
|
||||||
|
s_hasCachedDivisorCycle = true;
|
||||||
|
return cycleLength != 0UL;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
suppression.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static bool Pow2EqualsOneCpu(ulong exponent, ulong prime, in MontgomeryDivisorData divisorData)
|
private static bool Pow2EqualsOneCpu(ulong exponent, ulong prime, in MontgomeryDivisorData divisorData)
|
||||||
{
|
{
|
||||||
if (IsGpuPow2Allowed)
|
if (IsGpuPow2Allowed)
|
||||||
@@ -798,6 +884,11 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TryGetDivisorCycle(prime, divisorData, out ulong cycleLength) && cycleLength != 0UL)
|
||||||
|
{
|
||||||
|
return exponent.Pow2MontgomeryModWithCycleCpu(cycleLength, divisorData) == 1UL;
|
||||||
|
}
|
||||||
|
|
||||||
return exponent.Pow2MontgomeryModWindowedCpu(divisorData, keepMontgomery: false) == 1UL;
|
return exponent.Pow2MontgomeryModWindowedCpu(divisorData, keepMontgomery: false) == 1UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user