Extract divisor validator and rename legacy CPU prime helper
This commit is contained in:
1 parent
1e5eadac34
commit
3758524450
11 files changed
+67
-61
No files matched your search
@@ -0,0 +1,38 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace PerfectNumbers.Core;
|
||||
|
||||
internal static class DivisorGenerator
|
||||
{
|
||||
private const ushort DecimalMaskWhenLastIsSeven = (1 << 3) | (1 << 7) | (1 << 9);
|
||||
private const ushort DecimalMaskOtherwise = (1 << 1) | (1 << 3) | (1 << 9);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsValidDivisor(
|
||||
byte remainder10,
|
||||
byte remainder8,
|
||||
byte remainder3,
|
||||
byte remainder5,
|
||||
byte remainder7,
|
||||
byte remainder11,
|
||||
LastDigit lastDigit)
|
||||
{
|
||||
ushort decimalMask = lastDigit == LastDigit.Seven ? DecimalMaskWhenLastIsSeven : DecimalMaskOtherwise;
|
||||
if (((decimalMask >> remainder10) & 1) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (remainder8 != 1 && remainder8 != 7)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (remainder3 == 0 || remainder5 == 0 || remainder7 == 0 || remainder11 == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -263,7 +263,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
||||
{
|
||||
ulong candidate = (ulong)nextDivisor128;
|
||||
|
||||
if (CandidatePassesHeuristics(localRemainder10, localRemainder8, localRemainder3, localRemainder5, localRemainder7, localRemainder11, lastDigit))
|
||||
if (DivisorGenerator.IsValidDivisor(localRemainder10, localRemainder8, localRemainder3, localRemainder5, localRemainder7, localRemainder11, lastDigit))
|
||||
{
|
||||
filteredStorage[filteredCount++] = candidate;
|
||||
}
|
||||
@@ -378,38 +378,6 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
||||
return computedCycle;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool CandidatePassesHeuristics(
|
||||
byte remainder10,
|
||||
byte remainder8,
|
||||
byte remainder3,
|
||||
byte remainder5,
|
||||
byte remainder7,
|
||||
byte remainder11,
|
||||
LastDigit lastDigit)
|
||||
{
|
||||
const ushort DecimalMaskWhenLastIsSeven = (1 << 3) | (1 << 7) | (1 << 9);
|
||||
const ushort DecimalMaskOtherwise = (1 << 1) | (1 << 3) | (1 << 9);
|
||||
|
||||
ushort decimalMask = lastDigit == LastDigit.Seven ? DecimalMaskWhenLastIsSeven : DecimalMaskOtherwise;
|
||||
if (((decimalMask >> remainder10) & 1) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (remainder8 != 1 && remainder8 != 7)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (remainder3 == 0 || remainder5 == 0 || remainder7 == 0 || remainder11 == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static byte AddMod(byte value, byte delta, byte modulus)
|
||||
{
|
||||
|
||||
@@ -394,9 +394,9 @@ public class MersenneDivisorCycles
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Benchmark PrimeTester.IsPrimeCp against Open.Numeric.Primes on the EvenPerfectBitScanner workloads to confirm the faster option for wide composites.
|
||||
// TODO: Benchmark PrimeTester.IsPrimeCpu against Open.Numeric.Primes on the EvenPerfectBitScanner workloads to confirm the faster option for wide composites.
|
||||
// if (HeuristicPrimeTester.Exclusive.IsPrimeCpu(remaining, CancellationToken.None))
|
||||
if (PrimeTester.IsPrimeCp(remaining, CancellationToken.None))
|
||||
if (PrimeTester.IsPrimeCpu(remaining, CancellationToken.None))
|
||||
{
|
||||
AddFactor(counts, remaining);
|
||||
return true;
|
||||
@@ -929,7 +929,7 @@ public class MersenneDivisorCycles
|
||||
}
|
||||
|
||||
// if (!skipPrimeOrderHeuristic && HeuristicPrimeTester.Exclusive.IsPrimeCpu(divisor, CancellationToken.None))
|
||||
if (!skipPrimeOrderHeuristic && PrimeTester.IsPrimeCp(divisor, CancellationToken.None))
|
||||
if (!skipPrimeOrderHeuristic && PrimeTester.IsPrimeCpu(divisor, CancellationToken.None))
|
||||
{
|
||||
ulong computedOrder = PrimeOrderCalculator.Calculate(
|
||||
divisor,
|
||||
|
||||
@@ -26,7 +26,7 @@ public static class MersennePrimeFactorTester
|
||||
}
|
||||
|
||||
// if (!HeuristicPrimeTester.Exclusive.IsPrimeCpu(q, ct))
|
||||
if (!PrimeTester.IsPrimeCp(q, ct))
|
||||
if (!PrimeTester.IsPrimeCpu(q, ct))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -235,7 +235,7 @@ public static class MersennePrimeFactorTester
|
||||
}
|
||||
|
||||
// if (HeuristicPrimeTester.Exclusive.IsPrimeCpu(m, ct))
|
||||
if (PrimeTester.IsPrimeCp(m, ct))
|
||||
if (PrimeTester.IsPrimeCpu(m, ct))
|
||||
{
|
||||
dict[m] = 1;
|
||||
continue;
|
||||
|
||||
@@ -516,7 +516,7 @@ internal static partial class PrimeOrderCalculator
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (!PrimeTester.IsPrimeCp(orderFactors.Cofactor, CancellationToken.None))
|
||||
// if (!PrimeTester.IsPrimeCpu(orderFactors.Cofactor, CancellationToken.None))
|
||||
if (!orderFactors.CofactorIsPrime)
|
||||
{
|
||||
return false;
|
||||
@@ -1123,8 +1123,8 @@ internal static partial class PrimeOrderCalculator
|
||||
// }
|
||||
|
||||
// bool isPrime = primeTester.HeuristicIsPrimeGpu(composite);
|
||||
// bool isPrime = PrimeTester.IsPrimeCp(composite, CancellationToken.None);
|
||||
bool isPrime = PrimeTester.IsPrimeCp(composite, CancellationToken.None);
|
||||
// bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
||||
bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
||||
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
||||
|
||||
if (isPrime)
|
||||
@@ -1186,8 +1186,8 @@ internal static partial class PrimeOrderCalculator
|
||||
if (!entry.HasKnownPrimality)
|
||||
{
|
||||
// bool isPrime = primeTester.HeuristicIsPrimeGpu(composite);
|
||||
// bool isPrime = PrimeTester.IsPrimeCp(composite, CancellationToken.None);
|
||||
bool isPrime = PrimeTester.IsPrimeCp(composite, CancellationToken.None);
|
||||
// bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
||||
bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
||||
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
||||
|
||||
entry = entry.WithPrimality(isPrime);
|
||||
@@ -1219,8 +1219,8 @@ internal static partial class PrimeOrderCalculator
|
||||
else
|
||||
{
|
||||
// cofactorIsPrime = primeTester.HeuristicIsPrimeGpu(cofactor);
|
||||
// cofactorIsPrime = PrimeTester.IsPrimeCp(cofactor, CancellationToken.None);
|
||||
cofactorIsPrime = PrimeTester.IsPrimeCp(cofactor, CancellationToken.None);
|
||||
// cofactorIsPrime = PrimeTester.IsPrimeCpu(cofactor, CancellationToken.None);
|
||||
cofactorIsPrime = PrimeTester.IsPrimeCpu(cofactor, CancellationToken.None);
|
||||
// cofactorIsPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(cofactor);
|
||||
}
|
||||
|
||||
@@ -1752,8 +1752,8 @@ internal static partial class PrimeOrderCalculator
|
||||
PrimeTester primeTester = PrimeTester.Exclusive;
|
||||
|
||||
// bool isPrime = primeTester.HeuristicIsPrimeGpu(value);
|
||||
// bool isPrime = PrimeTester.IsPrimeCp(value, CancellationToken.None);
|
||||
bool isPrime = PrimeTester.IsPrimeCp(value, CancellationToken.None);
|
||||
// bool isPrime = PrimeTester.IsPrimeCpu(value, CancellationToken.None);
|
||||
bool isPrime = PrimeTester.IsPrimeCpu(value, CancellationToken.None);
|
||||
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(value);
|
||||
if (!knownComposite && isPrime)
|
||||
{
|
||||
@@ -1765,8 +1765,8 @@ internal static partial class PrimeOrderCalculator
|
||||
ulong quotient = value / factor;
|
||||
|
||||
// isPrime = primeTester.HeuristicIsPrimeGpu(factor);
|
||||
// isPrime = PrimeTester.IsPrimeCp(factor, CancellationToken.None);
|
||||
isPrime = PrimeTester.IsPrimeCp(factor, CancellationToken.None);
|
||||
// isPrime = PrimeTester.IsPrimeCpu(factor, CancellationToken.None);
|
||||
isPrime = PrimeTester.IsPrimeCpu(factor, CancellationToken.None);
|
||||
// isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(factor);
|
||||
if (isPrime)
|
||||
{
|
||||
@@ -1797,8 +1797,8 @@ internal static partial class PrimeOrderCalculator
|
||||
else
|
||||
{
|
||||
// isPrime = primeTester.HeuristicIsPrimeGpu(quotient);
|
||||
// isPrime = PrimeTester.IsPrimeCp(quotient, CancellationToken.None);
|
||||
isPrime = PrimeTester.IsPrimeCp(quotient, CancellationToken.None);
|
||||
// isPrime = PrimeTester.IsPrimeCpu(quotient, CancellationToken.None);
|
||||
isPrime = PrimeTester.IsPrimeCpu(quotient, CancellationToken.None);
|
||||
// isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(quotient);
|
||||
}
|
||||
|
||||
|
||||
@@ -956,7 +956,7 @@ internal static partial class PrimeOrderCalculator
|
||||
if (value <= ulong.MaxValue)
|
||||
{
|
||||
// return HeuristicPrimeTester.Exclusive.IsPrimeCpu((ulong)value, CancellationToken.None);
|
||||
return PrimeTester.IsPrimeCp((ulong)value, CancellationToken.None);
|
||||
return PrimeTester.IsPrimeCpu((ulong)value, CancellationToken.None);
|
||||
}
|
||||
|
||||
if ((value & UInt128.One) == UInt128.Zero)
|
||||
|
||||
@@ -93,10 +93,10 @@ public sealed class PrimeTester
|
||||
bool gpuReportedPrime = !forceCpu && !belowGpuRange && outFlags[0] != 0;
|
||||
bool requiresCpuFallback = forceCpu || belowGpuRange || !gpuReportedPrime;
|
||||
|
||||
return requiresCpuFallback ? IsPrimeCp(n, ct) : true;
|
||||
return requiresCpuFallback ? IsPrimeCpu(n, ct) : true;
|
||||
}
|
||||
|
||||
public static bool IsPrimeCp(ulong n, CancellationToken ct)
|
||||
public static bool IsPrimeCpu(ulong n, CancellationToken ct)
|
||||
{
|
||||
// Preserve the legacy entry point for callers that bypass the thread-local caches.
|
||||
return Exclusive.IsPrime(n, ct);
|
||||
|
||||
Reference in new issue
Block a user