Reuse pooled local cache for partial factor primality checks
This commit is contained in:
1 parent
b7c187bbc5
commit
0fbd635828
1 file changed
+18
-33
@@ -721,34 +721,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[ThreadStatic]
|
|
||||||
private static Dictionary<ulong, bool>? _partialFactorPrimalityCache;
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static void ResetPartialFactorPrimalityCache()
|
private static bool EvaluatePrimalityPartialFactor(ref Dictionary<ulong, bool>? localCache, ulong candidate)
|
||||||
{
|
|
||||||
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))
|
if (TryGetCachedPrimality(candidate, out bool cached))
|
||||||
{
|
{
|
||||||
@@ -758,7 +732,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
ulong globalCacheLimit = (ulong)PerfectNumberConstants.MaxQForDivisorCycles;
|
ulong globalCacheLimit = (ulong)PerfectNumberConstants.MaxQForDivisorCycles;
|
||||||
if (candidate > globalCacheLimit)
|
if (candidate > globalCacheLimit)
|
||||||
{
|
{
|
||||||
Dictionary<ulong, bool>? cache = _partialFactorPrimalityCache;
|
Dictionary<ulong, bool>? cache = localCache;
|
||||||
if (cache is not null && cache.TryGetValue(candidate, out bool cachedValue))
|
if (cache is not null && cache.TryGetValue(candidate, out bool cachedValue))
|
||||||
{
|
{
|
||||||
return cachedValue;
|
return cachedValue;
|
||||||
@@ -770,7 +744,13 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
if (candidate > globalCacheLimit)
|
if (candidate > globalCacheLimit)
|
||||||
{
|
{
|
||||||
Dictionary<ulong, bool> cache = GetPartialFactorPrimalityCache();
|
Dictionary<ulong, bool>? cache = localCache;
|
||||||
|
if (cache is null)
|
||||||
|
{
|
||||||
|
cache = ThreadStaticPools.RentUlongBoolDictionary(4);
|
||||||
|
localCache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
cache[candidate] = isPrime;
|
cache[candidate] = isPrime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -813,8 +793,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
List<PendingEntry> pending = ThreadStaticPools.RentPrimeOrderPendingEntryList(2);
|
List<PendingEntry> pending = ThreadStaticPools.RentPrimeOrderPendingEntryList(2);
|
||||||
Stack<ulong>? compositeStack = null;
|
Stack<ulong>? compositeStack = null;
|
||||||
PartialFactorResult result;
|
PartialFactorResult result;
|
||||||
|
Dictionary<ulong, bool>? primalityCache = null;
|
||||||
|
|
||||||
ResetPartialFactorPrimalityCache();
|
|
||||||
|
|
||||||
if (!gpuFactored)
|
if (!gpuFactored)
|
||||||
{
|
{
|
||||||
@@ -887,7 +867,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// continue;
|
// continue;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
bool isPrime = EvaluatePrimalityPartialFactor(composite);
|
bool isPrime = EvaluatePrimalityPartialFactor(ref primalityCache, composite);
|
||||||
|
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
{
|
{
|
||||||
@@ -937,7 +917,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPrime = EvaluatePrimalityPartialFactor(composite);
|
bool isPrime = EvaluatePrimalityPartialFactor(ref primalityCache, composite);
|
||||||
|
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
{
|
{
|
||||||
@@ -963,7 +943,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cofactorIsPrime = EvaluatePrimalityPartialFactor(cofactor);
|
cofactorIsPrime = EvaluatePrimalityPartialFactor(ref primalityCache, cofactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayPool<FactorEntry> pool = ThreadStaticPools.FactorEntryPool;
|
ArrayPool<FactorEntry> pool = ThreadStaticPools.FactorEntryPool;
|
||||||
@@ -1038,6 +1018,11 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// ThreadStaticPools.IntPool.Return(exponentSlotsArray);
|
// ThreadStaticPools.IntPool.Return(exponentSlotsArray);
|
||||||
|
|
||||||
|
|
||||||
|
if (primalityCache is not null)
|
||||||
|
{
|
||||||
|
ThreadStaticPools.ReturnUlongBoolDictionary(primalityCache);
|
||||||
|
}
|
||||||
|
|
||||||
if (counts is not null)
|
if (counts is not null)
|
||||||
{
|
{
|
||||||
ThreadStaticPools.ReturnUlongIntDictionary(counts);
|
ThreadStaticPools.ReturnUlongIntDictionary(counts);
|
||||||
|
|||||||
Reference in new issue
Block a user