Small optimizations
This commit is contained in:
1 parent
07395830a5
commit
aa4ff799f3
1 file changed
+43
-30
@@ -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++;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user