Small optimizations

This commit is contained in:
mlemanczyk committed 2025-10-16 19:46:25 +02:00
1 parent 07395830a5
commit aa4ff799f3
1 file changed
+43 -30
+43 -30
View File
@@ -793,10 +793,14 @@ internal static partial class PrimeOrderCalculator
}
const int FactorSlotCount = GpuSmallPrimeFactorSlots;
ulong[] primeSlotsArray = ThreadStaticPools.UlongPool.Rent(FactorSlotCount);
int[] exponentSlotsArray = ThreadStaticPools.IntPool.Rent(FactorSlotCount);
Span<ulong> primeSlots = primeSlotsArray.AsSpan(0, FactorSlotCount);
Span<int> exponentSlots = exponentSlotsArray.AsSpan(0, FactorSlotCount);
// stackalloc is faster than pooling
// ulong[] primeSlotsArray = ThreadStaticPools.UlongPool.Rent(FactorSlotCount);
// int[] exponentSlotsArray = ThreadStaticPools.IntPool.Rent(FactorSlotCount);
// Span<ulong> primeSlots = primeSlotsArray.AsSpan(0, FactorSlotCount);
// Span<int> exponentSlots = exponentSlotsArray.AsSpan(0, FactorSlotCount);
Span<ulong> primeSlots = stackalloc ulong[FactorSlotCount];
Span<int> exponentSlots = stackalloc int[FactorSlotCount];
// We don't need to worry about leftovers, because we always use indexes within the calculated counts
// primeSlots.Clear();
// exponentSlots.Clear();
@@ -839,7 +843,7 @@ internal static partial class PrimeOrderCalculator
if (config.PollardRhoMilliseconds > 0 && pending.Count > 0)
{
long deadlineTimestamp = CreateDeadlineTimestamp(config.PollardRhoMilliseconds);
compositeStack = ThreadStaticPools.RentUlongStack(Math.Max(pending.Count * 2, 4));
compositeStack = ThreadStaticPools.RentUlongStack(Math.Max(pending.Count << 1, 4));
compositeStack.Push(remaining);
pending.Clear();
@@ -847,10 +851,11 @@ internal static partial class PrimeOrderCalculator
while (compositeStack.Count > 0)
{
ulong composite = compositeStack.Pop();
if (composite <= 1UL)
{
continue;
}
// composite will never be smaller than 1 on the execution path
// if (composite <= 1UL)
// {
// continue;
// }
bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
if (isPrime)
@@ -888,7 +893,9 @@ internal static partial class PrimeOrderCalculator
{
AddFactorToCollector(ref useDictionary, ref counts, primeSlots, exponentSlots, ref factorCount, composite, 1);
}
else if (composite > 1UL)
// composite is never smaller on the execution path
// else if (composite > 1UL)
else
{
cofactor = checked(cofactor * composite);
}
@@ -967,8 +974,8 @@ internal static partial class PrimeOrderCalculator
result = PartialFactorResult.Rent(array, cofactor, fullyFactoredArray, arrayIndex);
ReturnResult:
ThreadStaticPools.UlongPool.Return(primeSlotsArray);
ThreadStaticPools.IntPool.Return(exponentSlotsArray);
// ThreadStaticPools.UlongPool.Return(primeSlotsArray);
// ThreadStaticPools.IntPool.Return(exponentSlotsArray);
if (counts is not null)
{
@@ -1055,16 +1062,18 @@ internal static partial class PrimeOrderCalculator
factorCount = 0;
remaining = value;
if (value <= 1UL)
{
return true;
}
// value will never <= 1 in production code
// if (value <= 1UL)
// {
// return true;
// }
int capacity = Math.Min(primeTargets.Length, exponentTargets.Length);
if (capacity == 0)
{
return false;
}
// capacity will never equal 0 in production code
// if (capacity == 0)
// {
// return false;
// }
uint[] primes = PrimesGenerator.SmallPrimes;
ulong[] squares = PrimesGenerator.SmallPrimesPow2;
@@ -1086,16 +1095,18 @@ internal static partial class PrimeOrderCalculator
}
ulong primeSquare = squares[i];
if (primeSquare != 0UL && primeSquare > remainingLocal)
// primeSquare will never == 0 in production code
// if (primeSquare != 0 && primeSquare > remainingLocal)
if (primeSquare > remainingLocal)
{
break;
}
ulong primeValue = primeCandidate;
if (primeValue == 0UL)
{
continue;
}
// primeCandidate will never equal 0 in production code
// if (primeCandidate == 0UL)
// {
// continue;
// }
ref CycleRemainderStepper stepper = ref cycleSteppers[i];
ulong remainder;
@@ -1131,20 +1142,22 @@ internal static partial class PrimeOrderCalculator
{
continue;
}
// TODO: Can we calculate this using residue steppers? We can try reusing modulo calculation for division result or the other way around
int exponent = 0;
do
{
remainingLocal /= primeValue;
remainingLocal /= primeCandidate;
exponent++;
}
while ((remainingLocal % primeValue) == 0UL);
while ((remainingLocal % primeCandidate) == 0UL);
if (factorCount >= capacity)
{
return false;
throw new InvalidOperationException($"Capacity is smaller than factor count");
}
primeTargets[factorCount] = primeValue;
primeTargets[factorCount] = primeCandidate;
exponentTargets[factorCount] = exponent;
factorCount++;
}