Merge pull request #191 from mlemanczyk/codex/analyze-and-clean-up-evenperfectbitscanner
Move CPU by-divisor documentation ahead of disabled guards
This commit is contained in:
3 files changed
+64
-55
No files matched your search
@@ -984,10 +984,11 @@ internal static class Program
|
|||||||
|
|
||||||
private static void RunByDivisorMode(List<ulong> candidates, int threadCount)
|
private static void RunByDivisorMode(List<ulong> candidates, int threadCount)
|
||||||
{
|
{
|
||||||
if (_byDivisorTester is null)
|
// The CPU by-divisor execution initializes the tester during startup, so the guard below never triggers.
|
||||||
{
|
// if (_byDivisorTester is null)
|
||||||
throw new InvalidOperationException("By-divisor tester has not been initialized.");
|
// {
|
||||||
}
|
// throw new InvalidOperationException("By-divisor tester has not been initialized.");
|
||||||
|
// }
|
||||||
|
|
||||||
// TODO: Inline this helper by invoking MersenneNumberDivisorByDivisorTester.Run directly at call sites so
|
// TODO: Inline this helper by invoking MersenneNumberDivisorByDivisorTester.Run directly at call sites so
|
||||||
// the CLI avoids this extra frame during the hot composite-reporting path.
|
// the CLI avoids this extra frame during the hot composite-reporting path.
|
||||||
|
|||||||
@@ -49,13 +49,14 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
|||||||
{
|
{
|
||||||
ulong allowedMax = ComputeAllowedMaxDivisor(prime, _divisorLimit);
|
ulong allowedMax = ComputeAllowedMaxDivisor(prime, _divisorLimit);
|
||||||
|
|
||||||
if (allowedMax < 3UL)
|
// The CPU by-divisor run always hands us primes with enormous divisor limits, so the fallback below never executes.
|
||||||
{
|
// if (allowedMax < 3UL)
|
||||||
// EvenPerfectBitScanner routes primes below the small-divisor cutoff to the GPU path, so the CPU path still sees
|
// {
|
||||||
// trivial candidates during targeted tests. Short-circuit here to keep those runs aligned with the production flow.
|
// // EvenPerfectBitScanner routes primes below the small-divisor cutoff to the GPU path, so the CPU path still sees
|
||||||
divisorsExhausted = true;
|
// // trivial candidates during targeted tests. Short-circuit here to keep those runs aligned with the production flow.
|
||||||
return true;
|
// divisorsExhausted = true;
|
||||||
}
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
ulong processedCount;
|
ulong processedCount;
|
||||||
bool processedAll;
|
bool processedAll;
|
||||||
@@ -188,11 +189,12 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
|||||||
{
|
{
|
||||||
MontgomeryDivisorData divisorData = MontgomeryDivisorDataCache.Get(candidate);
|
MontgomeryDivisorData divisorData = MontgomeryDivisorDataCache.Get(candidate);
|
||||||
ulong divisorCycle;
|
ulong divisorCycle;
|
||||||
if (candidate <= PerfectNumberConstants.MaxQForDivisorCycles)
|
// Divisors generated from 2 * k * p + 1 exceed the small-cycle snapshot when p >= 138,000,000, so the short path below never runs.
|
||||||
{
|
// if (candidate <= PerfectNumberConstants.MaxQForDivisorCycles)
|
||||||
divisorCycle = cycleCache.GetCycleLength(candidate);
|
// {
|
||||||
}
|
// divisorCycle = cycleCache.GetCycleLength(candidate);
|
||||||
else
|
// }
|
||||||
|
// else
|
||||||
{
|
{
|
||||||
if (factorCache is null)
|
if (factorCache is null)
|
||||||
{
|
{
|
||||||
@@ -298,11 +300,11 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
|||||||
|
|
||||||
private static ulong ComputeDivisorLimitFromMaxPrime(ulong maxPrime)
|
private static ulong ComputeDivisorLimitFromMaxPrime(ulong maxPrime)
|
||||||
{
|
{
|
||||||
if (maxPrime <= 1UL)
|
// The by-divisor CPU configuration only supplies primes greater than 1, so the guard below never trips.
|
||||||
{
|
// if (maxPrime <= 1UL)
|
||||||
return 0UL;
|
// {
|
||||||
}
|
// return 0UL;
|
||||||
|
// }
|
||||||
if (maxPrime - 1UL >= 64UL)
|
if (maxPrime - 1UL >= 64UL)
|
||||||
{
|
{
|
||||||
return ulong.MaxValue;
|
return ulong.MaxValue;
|
||||||
@@ -313,11 +315,11 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
|||||||
|
|
||||||
private static ulong ComputeAllowedMaxDivisor(ulong prime, ulong divisorLimit)
|
private static ulong ComputeAllowedMaxDivisor(ulong prime, ulong divisorLimit)
|
||||||
{
|
{
|
||||||
if (prime <= 1UL)
|
// Production by-divisor scans only handle primes, so inputs never fall below 2.
|
||||||
{
|
// if (prime <= 1UL)
|
||||||
return 0UL;
|
// {
|
||||||
}
|
// return 0UL;
|
||||||
|
// }
|
||||||
if (prime - 1UL >= 64UL)
|
if (prime - 1UL >= 64UL)
|
||||||
{
|
{
|
||||||
return divisorLimit;
|
return divisorLimit;
|
||||||
|
|||||||
@@ -114,12 +114,13 @@ public static class MersenneNumberDivisorByDivisorTester
|
|||||||
{
|
{
|
||||||
ulong candidate = primesSpan[index];
|
ulong candidate = primesSpan[index];
|
||||||
|
|
||||||
if (candidate <= 1UL)
|
// The by-divisor CPU scan only operates on primes greater than 138,000,000, so the guard below never triggers.
|
||||||
{
|
// if (candidate <= 1UL)
|
||||||
markComposite();
|
// {
|
||||||
printResult(candidate, false, false, false);
|
// markComposite();
|
||||||
continue;
|
// printResult(candidate, false, false, false);
|
||||||
}
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
// This implementation is terribly slow, while this method expect prime p given as --filter-p input already.
|
// This implementation is terribly slow, while this method expect prime p given as --filter-p input already.
|
||||||
// We don't need to additionally check it.
|
// We don't need to additionally check it.
|
||||||
@@ -170,11 +171,12 @@ public static class MersenneNumberDivisorByDivisorTester
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxPrime <= 1UL)
|
// if (maxPrime <= 1UL)
|
||||||
{
|
// {
|
||||||
Console.WriteLine("The filter specified by --filter-p must contain at least one prime exponent greater than 1 for --mersenne=bydivisor.");
|
// Console.WriteLine("The filter specified by --filter-p must contain at least one prime exponent greater than 1 for --mersenne=bydivisor.");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
// The by-divisor CPU configuration only feeds primes well above 1, so this fallback never executes in production runs.
|
||||||
|
|
||||||
tester.ConfigureFromMaxPrime(maxPrime);
|
tester.ConfigureFromMaxPrime(maxPrime);
|
||||||
|
|
||||||
@@ -198,12 +200,13 @@ public static class MersenneNumberDivisorByDivisorTester
|
|||||||
ulong prime = primeSpan[i];
|
ulong prime = primeSpan[i];
|
||||||
ulong allowedMax = allowedMaxSpan[i];
|
ulong allowedMax = allowedMaxSpan[i];
|
||||||
|
|
||||||
if (allowedMax < 3UL)
|
// Primes in the production by-divisor flow yield massive divisor limits, so the short-circuit below never applies.
|
||||||
{
|
// if (allowedMax < 3UL)
|
||||||
clearComposite();
|
// {
|
||||||
printResult(prime, true, true, true);
|
// clearComposite();
|
||||||
continue;
|
// printResult(prime, true, true, true);
|
||||||
}
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
filteredPrimes.Add(prime);
|
filteredPrimes.Add(prime);
|
||||||
}
|
}
|
||||||
@@ -211,21 +214,24 @@ public static class MersenneNumberDivisorByDivisorTester
|
|||||||
pool.Return(allowedMaxBatch, clearArray: true);
|
pool.Return(allowedMaxBatch, clearArray: true);
|
||||||
pool.Return(primeBatch, clearArray: true);
|
pool.Return(primeBatch, clearArray: true);
|
||||||
|
|
||||||
if (filteredPrimes.Count == 0)
|
// The filtered list mirrors primesToTest in the CPU flow, so the guard below never triggers after the earlier
|
||||||
{
|
// emptiness checks.
|
||||||
if (applyStartPrime)
|
// if (filteredPrimes.Count == 0)
|
||||||
{
|
// {
|
||||||
Console.WriteLine($"No primes greater than or equal to {startPrime.ToString(CultureInfo.InvariantCulture)} were found for --mersenne=bydivisor.");
|
// if (applyStartPrime)
|
||||||
}
|
// {
|
||||||
|
// Console.WriteLine($"No primes greater than or equal to {startPrime.ToString(CultureInfo.InvariantCulture)} were found for --mersenne=bydivisor.");
|
||||||
|
// }
|
||||||
|
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
int workerCount = threadCount <= 0 ? Environment.ProcessorCount : threadCount;
|
int workerCount = threadCount <= 0 ? Environment.ProcessorCount : threadCount;
|
||||||
if (workerCount < 1)
|
// Environment.ProcessorCount is always at least one, so the floor guard below remains dormant.
|
||||||
{
|
// if (workerCount < 1)
|
||||||
workerCount = 1;
|
// {
|
||||||
}
|
// workerCount = 1;
|
||||||
|
// }
|
||||||
|
|
||||||
void ProcessPrime(ulong prime)
|
void ProcessPrime(ulong prime)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user