PrimeOrderCalculator.PartialFactorCpu variables optimized. Removed constant parameter from AddFactorToCollector.
This commit is contained in:
1 parent
0fb5a5fa10
commit
1b3882addc
4 files changed
+31
-62
No files matched your search
@@ -2,6 +2,7 @@ using System.Runtime.CompilerServices;
|
|||||||
|
|
||||||
namespace PerfectNumbers.Core;
|
namespace PerfectNumbers.Core;
|
||||||
|
|
||||||
|
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public struct PartialFactorPendingEntry(ulong value, bool knownComposite)
|
public struct PartialFactorPendingEntry(ulong value, bool knownComposite)
|
||||||
{
|
{
|
||||||
public readonly ulong Value = value;
|
public readonly ulong Value = value;
|
||||||
|
|||||||
@@ -1319,20 +1319,21 @@ internal static partial class PrimeOrderCalculator
|
|||||||
primeSlots,
|
primeSlots,
|
||||||
exponentSlots,
|
exponentSlots,
|
||||||
out int factorCount,
|
out int factorCount,
|
||||||
out ulong remaining);
|
out value);
|
||||||
|
|
||||||
if (remaining > 1UL)
|
bool cofactorContainsComposite;
|
||||||
|
if (value > 1UL)
|
||||||
{
|
{
|
||||||
if (config.PollardRhoMilliseconds > 0)
|
if (config.PollardRhoMilliseconds > 0)
|
||||||
{
|
{
|
||||||
long deadlineTimestamp = CreateDeadlineTimestamp(config.PollardRhoMilliseconds);
|
|
||||||
FixedCapacityStack<ulong> compositeStack = result.CompositeStack;
|
FixedCapacityStack<ulong> compositeStack = result.CompositeStack;
|
||||||
compositeStack.Clear();
|
compositeStack.Clear();
|
||||||
compositeStack.Push(remaining);
|
compositeStack.Push(value);
|
||||||
|
long deadlineTimestamp = CreateDeadlineTimestamp(config.PollardRhoMilliseconds);
|
||||||
|
|
||||||
CollectFactorsCpu(primeSlots, exponentSlots, ref factorCount, pending, compositeStack, deadlineTimestamp, out bool limitReached);
|
CollectFactorsCpu(primeSlots, exponentSlots, ref factorCount, pending, compositeStack, deadlineTimestamp, out cofactorContainsComposite);
|
||||||
|
|
||||||
if (limitReached)
|
if (cofactorContainsComposite)
|
||||||
{
|
{
|
||||||
while (compositeStack.Count > 0)
|
while (compositeStack.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -1342,72 +1343,61 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pending.Add(new (remaining, knownComposite: false));
|
pending.Add(new (value, knownComposite: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong cofactor = 1UL;
|
ulong cofactor = 1UL;
|
||||||
bool cofactorContainsComposite = false;
|
bool isPrime;
|
||||||
int pendingCount = pending.Count;
|
int pendingCount = pending.Count;
|
||||||
int index = 0;
|
cofactorContainsComposite = false;
|
||||||
|
|
||||||
for (; index < pendingCount; index++)
|
for (int index = 0; index < pendingCount; index++)
|
||||||
{
|
{
|
||||||
PartialFactorPendingEntry entry = pending[index];
|
PartialFactorPendingEntry entry = pending[index];
|
||||||
ulong composite = entry.Value;
|
// Reuse "value" parameter for testing if a number is composite to limit registry pressure.
|
||||||
|
value = entry.Value;
|
||||||
|
|
||||||
if (entry.KnownComposite)
|
if (entry.KnownComposite)
|
||||||
{
|
{
|
||||||
cofactor = checked(cofactor * composite);
|
cofactor = checked(cofactor * value);
|
||||||
cofactorContainsComposite = true;
|
cofactorContainsComposite = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!entry.HasKnownPrimality)
|
if (!entry.HasKnownPrimality)
|
||||||
{
|
{
|
||||||
bool isPrime = PrimeTesterByLastDigit.IsPrimeCpu(composite);
|
isPrime = PrimeTesterByLastDigit.IsPrimeCpu(value);
|
||||||
|
|
||||||
entry.WithPrimality(isPrime);
|
entry.WithPrimality(isPrime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.IsPrime)
|
if (entry.IsPrime)
|
||||||
{
|
{
|
||||||
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, composite, 1);
|
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, value);
|
||||||
}
|
}
|
||||||
// composite is never smaller on the execution path
|
// composite is never smaller on the execution path
|
||||||
// else if (composite > 1UL)
|
// else if (composite > 1UL)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cofactor = checked(cofactor * composite);
|
cofactor = checked(cofactor * value);
|
||||||
cofactorContainsComposite = true;
|
cofactorContainsComposite = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cofactorIsPrime;
|
if (cofactorContainsComposite || cofactor <= 1UL)
|
||||||
if (cofactor <= 1UL)
|
|
||||||
{
|
{
|
||||||
cofactorIsPrime = false;
|
isPrime = false;
|
||||||
}
|
|
||||||
else if (cofactorContainsComposite)
|
|
||||||
{
|
|
||||||
cofactorIsPrime = false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cofactorIsPrime = PrimeTesterByLastDigit.IsPrimeCpu(cofactor);
|
isPrime = PrimeTesterByLastDigit.IsPrimeCpu(cofactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will never happen in production code. We'll always get at least 1 factor
|
// This will never happen in production code. We'll always get at least 1 factor
|
||||||
// if (factorCount == 0)
|
// if (factorCount == 0)
|
||||||
// {
|
// {
|
||||||
// if (cofactor == value)
|
// (...)
|
||||||
// {
|
|
||||||
// result = PartialFactorResult.Rent(null, value, false, 0);
|
|
||||||
// goto ReturnResult;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// result = PartialFactorResult.Rent(null, cofactor, cofactor == 1UL, 0);
|
|
||||||
// goto ReturnResult;
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
Array.Sort(factors, exponents, 0, factorCount);
|
Array.Sort(factors, exponents, 0, factorCount);
|
||||||
@@ -1417,7 +1407,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
result.Cofactor = cofactor;
|
result.Cofactor = cofactor;
|
||||||
result.FullyFactored = cofactor == 1UL;
|
result.FullyFactored = cofactor == 1UL;
|
||||||
result.Count = factorCount;
|
result.Count = factorCount;
|
||||||
result.CofactorIsPrime = cofactorIsPrime;
|
result.CofactorIsPrime = isPrime;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1432,7 +1422,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
{
|
{
|
||||||
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, composite, 1);
|
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, composite);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1511,10 +1501,6 @@ internal static partial class PrimeOrderCalculator
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnsureCollectorCapacity(
|
|
||||||
primeTargets,
|
|
||||||
factorCount + 1);
|
|
||||||
|
|
||||||
primeTargets[factorCount] = primeValue;
|
primeTargets[factorCount] = primeValue;
|
||||||
exponentTargets[factorCount] = exponent;
|
exponentTargets[factorCount] = exponent;
|
||||||
factorCount++;
|
factorCount++;
|
||||||
@@ -1722,40 +1708,22 @@ internal static partial class PrimeOrderCalculator
|
|||||||
Span<ulong> primes,
|
Span<ulong> primes,
|
||||||
Span<int> exponents,
|
Span<int> exponents,
|
||||||
ref int count,
|
ref int count,
|
||||||
ulong prime,
|
ulong prime)
|
||||||
int exponent)
|
|
||||||
{
|
{
|
||||||
if (exponent <= 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (primes[i] == prime)
|
if (primes[i] == prime)
|
||||||
{
|
{
|
||||||
exponents[i] += exponent;
|
exponents[i]++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EnsureCollectorCapacity(
|
|
||||||
primes,
|
|
||||||
count + 1);
|
|
||||||
|
|
||||||
primes[count] = prime;
|
primes[count] = prime;
|
||||||
exponents[count] = exponent;
|
exponents[count] = 1;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
|
||||||
private static void EnsureCollectorCapacity(
|
|
||||||
Span<ulong> primes,
|
|
||||||
int requiredCapacity)
|
|
||||||
{
|
|
||||||
ArgumentOutOfRangeException.ThrowIfGreaterThan(requiredCapacity, primes.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||||
private static ulong CalculateByFactorizationCpu(ulong prime, in MontgomeryDivisorData divisorData)
|
private static ulong CalculateByFactorizationCpu(ulong prime, in MontgomeryDivisorData divisorData)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
{
|
{
|
||||||
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, composite, 1);
|
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, composite);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,7 +426,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
if (entry.IsPrime)
|
if (entry.IsPrime)
|
||||||
{
|
{
|
||||||
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, composite, 1);
|
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, composite);
|
||||||
}
|
}
|
||||||
// composite is never smaller on the execution path
|
// composite is never smaller on the execution path
|
||||||
// else if (composite > 1UL)
|
// else if (composite > 1UL)
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
{
|
{
|
||||||
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, composite, 1);
|
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, composite);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +218,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
if (entry.IsPrime)
|
if (entry.IsPrime)
|
||||||
{
|
{
|
||||||
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, composite, 1);
|
AddFactorToCollector(primeSlots, exponentSlots, ref factorCount, composite);
|
||||||
}
|
}
|
||||||
// composite is never smaller on the execution path
|
// composite is never smaller on the execution path
|
||||||
// else if (composite > 1UL)
|
// else if (composite > 1UL)
|
||||||
|
|||||||
Reference in new issue
Block a user