Restore pooled small factor buffers

This commit is contained in:
Marek Lemańczyk committed 2025-10-16 17:18:19 +02:00
1 parent 949b5f891c
commit fb08a61c66
2 files changed
+49 -26

No files matched your search

+37 -26
View File
@@ -781,8 +781,10 @@ internal static partial class PrimeOrderCalculator
} }
const int FactorSlotCount = GpuSmallPrimeFactorSlots; const int FactorSlotCount = GpuSmallPrimeFactorSlots;
Span<ulong> primeSlots = stackalloc ulong[FactorSlotCount]; ulong[] primeSlotsArray = ThreadStaticPools.UlongPool.Rent(FactorSlotCount);
Span<int> exponentSlots = stackalloc int[FactorSlotCount]; int[] exponentSlotsArray = ThreadStaticPools.IntPool.Rent(FactorSlotCount);
Span<ulong> primeSlots = primeSlotsArray.AsSpan(0, FactorSlotCount);
Span<int> exponentSlots = exponentSlotsArray.AsSpan(0, FactorSlotCount);
primeSlots.Clear(); primeSlots.Clear();
exponentSlots.Clear(); exponentSlots.Clear();
@@ -951,6 +953,9 @@ internal static partial class PrimeOrderCalculator
result = PartialFactorResult.Rent(array, cofactor, fullyFactoredArray, arrayIndex); result = PartialFactorResult.Rent(array, cofactor, fullyFactoredArray, arrayIndex);
ReturnResult: ReturnResult:
ThreadStaticPools.UlongPool.Return(primeSlotsArray);
ThreadStaticPools.IntPool.Return(exponentSlotsArray);
if (counts is not null) if (counts is not null)
{ {
ThreadStaticPools.ReturnUlongIntDictionary(counts); ThreadStaticPools.ReturnUlongIntDictionary(counts);
@@ -1079,34 +1084,40 @@ internal static partial class PrimeOrderCalculator
return remaining; return remaining;
} }
private static bool TryPopulateSmallPrimeFactorsGpu(ulong value, uint limit, Dictionary<ulong, int> counts, out ulong remaining) private static bool TryPopulateSmallPrimeFactorsGpu(ulong value, uint limit, Dictionary<ulong, int> counts, out ulong remaining)
{ {
Span<ulong> primeBuffer = stackalloc ulong[GpuSmallPrimeFactorSlots]; ulong[] primeBufferArray = ThreadStaticPools.UlongPool.Rent(GpuSmallPrimeFactorSlots);
Span<int> exponentBuffer = stackalloc int[GpuSmallPrimeFactorSlots]; int[] exponentBufferArray = ThreadStaticPools.IntPool.Rent(GpuSmallPrimeFactorSlots);
primeBuffer.Clear(); Span<ulong> primeBuffer = primeBufferArray.AsSpan(0, GpuSmallPrimeFactorSlots);
exponentBuffer.Clear(); Span<int> exponentBuffer = exponentBufferArray.AsSpan(0, GpuSmallPrimeFactorSlots);
primeBuffer.Clear();
exponentBuffer.Clear();
if (!PrimeOrderGpuHeuristics.TryPartialFactor(value, limit, primeBuffer, exponentBuffer, out int factorCount, out ulong gpuRemaining, out _)) if (!PrimeOrderGpuHeuristics.TryPartialFactor(value, limit, primeBuffer, exponentBuffer, out int factorCount, out ulong gpuRemaining, out _))
{ {
remaining = value; remaining = value;
return false; ThreadStaticPools.UlongPool.Return(primeBufferArray);
} ThreadStaticPools.IntPool.Return(exponentBufferArray);
return false;
}
remaining = gpuRemaining; remaining = gpuRemaining;
for (int i = 0; i < factorCount; i++) for (int i = 0; i < factorCount; i++)
{ {
ulong primeValue = primeBuffer[i]; ulong primeValue = primeBuffer[i];
int exponent = exponentBuffer[i]; int exponent = exponentBuffer[i];
if (primeValue == 0UL || exponent == 0) if (primeValue == 0UL || exponent == 0)
{ {
continue; continue;
} }
counts[primeValue] = exponent; counts[primeValue] = exponent;
} }
return true; ThreadStaticPools.UlongPool.Return(primeBufferArray);
} ThreadStaticPools.IntPool.Return(exponentBufferArray);
return true;
}
private static long CreateDeadlineTimestamp(int milliseconds) private static long CreateDeadlineTimestamp(int milliseconds)
{ {
if (milliseconds <= 0) if (milliseconds <= 0)
+12
View File
@@ -79,6 +79,18 @@ namespace PerfectNumbers.Core
} }
} }
[ThreadStatic]
private static ArrayPool<int>? _intPool;
public static ArrayPool<int> IntPool
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return _intPool ??= ArrayPool<int>.Create();
}
}
[ThreadStatic] [ThreadStatic]
private static List<List<ulong>>? _ulongListPool; private static List<List<ulong>>? _ulongListPool;