Make partial factor primality cache thread static
This commit is contained in:
1 parent
627d2e9b14
commit
4917f690fc
1 file changed
+61
-27
@@ -720,6 +720,63 @@ internal static partial class PrimeOrderCalculator
|
|||||||
return isPrime;
|
return isPrime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[ThreadStatic]
|
||||||
|
private static Dictionary<ulong, bool>? _partialFactorPrimalityCache;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static void ResetPartialFactorPrimalityCache()
|
||||||
|
{
|
||||||
|
Dictionary<ulong, bool>? cache = _partialFactorPrimalityCache;
|
||||||
|
if (cache is not null && cache.Count > 0)
|
||||||
|
{
|
||||||
|
cache.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static Dictionary<ulong, bool> GetPartialFactorPrimalityCache()
|
||||||
|
{
|
||||||
|
Dictionary<ulong, bool>? cache = _partialFactorPrimalityCache;
|
||||||
|
if (cache is null)
|
||||||
|
{
|
||||||
|
cache = ThreadStaticPools.RentUlongBoolDictionary(4);
|
||||||
|
_partialFactorPrimalityCache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static bool EvaluatePrimalityPartialFactor(ulong candidate)
|
||||||
|
{
|
||||||
|
if (TryGetCachedPrimality(candidate, out bool cached))
|
||||||
|
{
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong globalCacheLimit = (ulong)PerfectNumberConstants.MaxQForDivisorCycles;
|
||||||
|
if (candidate > globalCacheLimit)
|
||||||
|
{
|
||||||
|
Dictionary<ulong, bool>? cache = _partialFactorPrimalityCache;
|
||||||
|
if (cache is not null && cache.TryGetValue(candidate, out bool cachedValue))
|
||||||
|
{
|
||||||
|
return cachedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(candidate);
|
||||||
|
CachePrimalityResult(candidate, isPrime);
|
||||||
|
|
||||||
|
if (candidate > globalCacheLimit)
|
||||||
|
{
|
||||||
|
Dictionary<ulong, bool> cache = GetPartialFactorPrimalityCache();
|
||||||
|
cache[candidate] = isPrime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isPrime;
|
||||||
|
}
|
||||||
|
|
||||||
private static PartialFactorResult PartialFactor(ulong value, in PrimeOrderSearchConfig config)
|
private static PartialFactorResult PartialFactor(ulong value, in PrimeOrderSearchConfig config)
|
||||||
{
|
{
|
||||||
if (value <= 1UL)
|
if (value <= 1UL)
|
||||||
@@ -757,26 +814,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
Stack<ulong>? compositeStack = null;
|
Stack<ulong>? compositeStack = null;
|
||||||
PartialFactorResult result;
|
PartialFactorResult result;
|
||||||
|
|
||||||
Dictionary<ulong, bool>? localPrimalityCache = null;
|
ResetPartialFactorPrimalityCache();
|
||||||
|
|
||||||
bool EvaluatePrimality(ulong candidate)
|
|
||||||
{
|
|
||||||
Dictionary<ulong, bool>? cache = localPrimalityCache;
|
|
||||||
if (cache is not null && cache.TryGetValue(candidate, out bool cachedValue))
|
|
||||||
{
|
|
||||||
return cachedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool computed = GetOrComputePrimality(candidate);
|
|
||||||
if (!computed)
|
|
||||||
{
|
|
||||||
cache ??= ThreadStaticPools.RentUlongBoolDictionary(4);
|
|
||||||
cache[candidate] = false;
|
|
||||||
localPrimalityCache = cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
return computed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gpuFactored)
|
if (!gpuFactored)
|
||||||
{
|
{
|
||||||
@@ -842,7 +880,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// continue;
|
// continue;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
bool isPrime = EvaluatePrimality(composite);
|
bool isPrime = EvaluatePrimalityPartialFactor(composite);
|
||||||
|
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
{
|
{
|
||||||
@@ -889,7 +927,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPrime = EvaluatePrimality(composite);
|
bool isPrime = EvaluatePrimalityPartialFactor(composite);
|
||||||
|
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
{
|
{
|
||||||
@@ -915,7 +953,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cofactorIsPrime = EvaluatePrimality(cofactor);
|
cofactorIsPrime = EvaluatePrimalityPartialFactor(cofactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayPool<FactorEntry> pool = ThreadStaticPools.FactorEntryPool;
|
ArrayPool<FactorEntry> pool = ThreadStaticPools.FactorEntryPool;
|
||||||
@@ -989,10 +1027,6 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// ThreadStaticPools.UlongPool.Return(primeSlotsArray);
|
// ThreadStaticPools.UlongPool.Return(primeSlotsArray);
|
||||||
// ThreadStaticPools.IntPool.Return(exponentSlotsArray);
|
// ThreadStaticPools.IntPool.Return(exponentSlotsArray);
|
||||||
|
|
||||||
if (localPrimalityCache is not null)
|
|
||||||
{
|
|
||||||
ThreadStaticPools.ReturnUlongBoolDictionary(localPrimalityCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (counts is not null)
|
if (counts is not null)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user