Make partial factor primality cache thread static

This commit is contained in:
Marek Lemańczyk committed 2025-10-19 22:59:44 +02:00
1 parent 627d2e9b14
commit 4917f690fc
1 file changed
+61 -27
+61 -27
View File
@@ -720,6 +720,63 @@ internal static partial class PrimeOrderCalculator
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)
{
if (value <= 1UL)
@@ -757,26 +814,7 @@ internal static partial class PrimeOrderCalculator
Stack<ulong>? compositeStack = null;
PartialFactorResult result;
Dictionary<ulong, bool>? localPrimalityCache = null;
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;
}
ResetPartialFactorPrimalityCache();
if (!gpuFactored)
{
@@ -842,7 +880,7 @@ internal static partial class PrimeOrderCalculator
// continue;
// }
bool isPrime = EvaluatePrimality(composite);
bool isPrime = EvaluatePrimalityPartialFactor(composite);
if (isPrime)
{
@@ -889,7 +927,7 @@ internal static partial class PrimeOrderCalculator
continue;
}
bool isPrime = EvaluatePrimality(composite);
bool isPrime = EvaluatePrimalityPartialFactor(composite);
if (isPrime)
{
@@ -915,7 +953,7 @@ internal static partial class PrimeOrderCalculator
}
else
{
cofactorIsPrime = EvaluatePrimality(cofactor);
cofactorIsPrime = EvaluatePrimalityPartialFactor(cofactor);
}
ArrayPool<FactorEntry> pool = ThreadStaticPools.FactorEntryPool;
@@ -989,10 +1027,6 @@ internal static partial class PrimeOrderCalculator
// ThreadStaticPools.UlongPool.Return(primeSlotsArray);
// ThreadStaticPools.IntPool.Return(exponentSlotsArray);
if (localPrimalityCache is not null)
{
ThreadStaticPools.ReturnUlongBoolDictionary(localPrimalityCache);
}
if (counts is not null)
{