Filter CPU divisor checks by admissible residues

This commit is contained in:
Marek Lemańczyk committed 2025-10-08 19:23:09 +02:00
1 parent 26abc2dfa8
commit 85634da6eb
1 file changed
+34
@@ -192,12 +192,30 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
Dictionary<ulong, MersenneDivisorCycles.FactorCacheEntry>? factorCache = null; Dictionary<ulong, MersenneDivisorCycles.FactorCacheEntry>? factorCache = null;
DivisorCycleCache cycleCache = DivisorCycleCache.Shared; DivisorCycleCache cycleCache = DivisorCycleCache.Shared;
byte step10 = (byte)(step % 10UL);
byte step8 = (byte)(step % 8UL);
byte step5 = (byte)(step % 5UL);
byte step3 = (byte)(step % 3UL);
byte remainder10 = (byte)(divisor % 10UL);
byte remainder8 = (byte)(divisor % 8UL);
byte remainder5 = (byte)(divisor % 5UL);
byte remainder3 = (byte)(divisor % 3UL);
bool lastIsSeven = (prime & 3UL) == 3UL;
while (divisor <= limit) while (divisor <= limit)
{ {
ulong candidate = (ulong)divisor; ulong candidate = (ulong)divisor;
processedCount++; processedCount++;
lastProcessed = candidate; lastProcessed = candidate;
bool admissible = lastIsSeven
? (remainder10 == 3 || remainder10 == 7 || remainder10 == 9)
: (remainder10 == 1 || remainder10 == 3 || remainder10 == 7 || remainder10 == 9);
if (admissible && (remainder8 == 1 || remainder8 == 7) && remainder3 != 0 && remainder5 != 0)
{
MontgomeryDivisorData divisorData = MontgomeryDivisorDataCache.Get(candidate); MontgomeryDivisorData divisorData = MontgomeryDivisorDataCache.Get(candidate);
ulong divisorCycle = 0UL; ulong divisorCycle = 0UL;
@@ -219,8 +237,13 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
processedAll = true; processedAll = true;
return true; return true;
} }
}
divisor += step; divisor += step;
remainder10 = AddMod(remainder10, step10, (byte)10);
remainder8 = AddMod(remainder8, step8, (byte)8);
remainder5 = AddMod(remainder5, step5, (byte)5);
remainder3 = AddMod(remainder3, step3, (byte)3);
} }
processedAll = divisor > limit; processedAll = divisor > limit;
@@ -233,6 +256,17 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
return residue == 1UL ? (byte)1 : (byte)0; return residue == 1UL ? (byte)1 : (byte)0;
} }
private static byte AddMod(byte value, byte delta, byte modulus)
{
int sum = value + delta;
if (sum >= modulus)
{
sum -= modulus;
}
return (byte)sum;
}
private void UpdateStatusUnsafe(ulong lastProcessed, ulong processedCount) private void UpdateStatusUnsafe(ulong lastProcessed, ulong processedCount)
{ {
if (processedCount == 0UL) if (processedCount == 0UL)