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;
|
const int FactorSlotCount = GpuSmallPrimeFactorSlots;
|
||||||
ulong[] primeSlotsArray = ThreadStaticPools.UlongPool.Rent(FactorSlotCount);
|
|
||||||
int[] exponentSlotsArray = ThreadStaticPools.IntPool.Rent(FactorSlotCount);
|
// stackalloc is faster than pooling
|
||||||
Span<ulong> primeSlots = primeSlotsArray.AsSpan(0, FactorSlotCount);
|
// ulong[] primeSlotsArray = ThreadStaticPools.UlongPool.Rent(FactorSlotCount);
|
||||||
Span<int> exponentSlots = exponentSlotsArray.AsSpan(0, 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
|
// We don't need to worry about leftovers, because we always use indexes within the calculated counts
|
||||||
// primeSlots.Clear();
|
// primeSlots.Clear();
|
||||||
// exponentSlots.Clear();
|
// exponentSlots.Clear();
|
||||||
@@ -839,7 +843,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
if (config.PollardRhoMilliseconds > 0 && pending.Count > 0)
|
if (config.PollardRhoMilliseconds > 0 && pending.Count > 0)
|
||||||
{
|
{
|
||||||
long deadlineTimestamp = CreateDeadlineTimestamp(config.PollardRhoMilliseconds);
|
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);
|
compositeStack.Push(remaining);
|
||||||
pending.Clear();
|
pending.Clear();
|
||||||
|
|
||||||
@@ -847,10 +851,11 @@ internal static partial class PrimeOrderCalculator
|
|||||||
while (compositeStack.Count > 0)
|
while (compositeStack.Count > 0)
|
||||||
{
|
{
|
||||||
ulong composite = compositeStack.Pop();
|
ulong composite = compositeStack.Pop();
|
||||||
if (composite <= 1UL)
|
// composite will never be smaller than 1 on the execution path
|
||||||
{
|
// if (composite <= 1UL)
|
||||||
continue;
|
// {
|
||||||
}
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
@@ -888,7 +893,9 @@ internal static partial class PrimeOrderCalculator
|
|||||||
{
|
{
|
||||||
AddFactorToCollector(ref useDictionary, ref counts, primeSlots, exponentSlots, ref factorCount, composite, 1);
|
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);
|
cofactor = checked(cofactor * composite);
|
||||||
}
|
}
|
||||||
@@ -967,8 +974,8 @@ 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.UlongPool.Return(primeSlotsArray);
|
||||||
ThreadStaticPools.IntPool.Return(exponentSlotsArray);
|
// ThreadStaticPools.IntPool.Return(exponentSlotsArray);
|
||||||
|
|
||||||
if (counts is not null)
|
if (counts is not null)
|
||||||
{
|
{
|
||||||
@@ -1055,16 +1062,18 @@ internal static partial class PrimeOrderCalculator
|
|||||||
factorCount = 0;
|
factorCount = 0;
|
||||||
remaining = value;
|
remaining = value;
|
||||||
|
|
||||||
if (value <= 1UL)
|
// value will never <= 1 in production code
|
||||||
{
|
// if (value <= 1UL)
|
||||||
return true;
|
// {
|
||||||
}
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
int capacity = Math.Min(primeTargets.Length, exponentTargets.Length);
|
int capacity = Math.Min(primeTargets.Length, exponentTargets.Length);
|
||||||
if (capacity == 0)
|
// capacity will never equal 0 in production code
|
||||||
{
|
// if (capacity == 0)
|
||||||
return false;
|
// {
|
||||||
}
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
uint[] primes = PrimesGenerator.SmallPrimes;
|
uint[] primes = PrimesGenerator.SmallPrimes;
|
||||||
ulong[] squares = PrimesGenerator.SmallPrimesPow2;
|
ulong[] squares = PrimesGenerator.SmallPrimesPow2;
|
||||||
@@ -1086,16 +1095,18 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
|
|
||||||
ulong primeSquare = squares[i];
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong primeValue = primeCandidate;
|
// primeCandidate will never equal 0 in production code
|
||||||
if (primeValue == 0UL)
|
// if (primeCandidate == 0UL)
|
||||||
{
|
// {
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
|
||||||
ref CycleRemainderStepper stepper = ref cycleSteppers[i];
|
ref CycleRemainderStepper stepper = ref cycleSteppers[i];
|
||||||
ulong remainder;
|
ulong remainder;
|
||||||
@@ -1131,20 +1142,22 @@ internal static partial class PrimeOrderCalculator
|
|||||||
{
|
{
|
||||||
continue;
|
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;
|
int exponent = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
remainingLocal /= primeValue;
|
remainingLocal /= primeCandidate;
|
||||||
exponent++;
|
exponent++;
|
||||||
}
|
}
|
||||||
while ((remainingLocal % primeValue) == 0UL);
|
while ((remainingLocal % primeCandidate) == 0UL);
|
||||||
|
|
||||||
if (factorCount >= capacity)
|
if (factorCount >= capacity)
|
||||||
{
|
{
|
||||||
return false;
|
throw new InvalidOperationException($"Capacity is smaller than factor count");
|
||||||
}
|
}
|
||||||
|
|
||||||
primeTargets[factorCount] = primeValue;
|
primeTargets[factorCount] = primeCandidate;
|
||||||
exponentTargets[factorCount] = exponent;
|
exponentTargets[factorCount] = exponent;
|
||||||
factorCount++;
|
factorCount++;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user