IsPrime optimized to do more operations outside of the lock.

This commit is contained in:
Marek Lemańczyk committed 2025-09-24 01:58:02 +02:00
1 parent cc834687fd
commit 4d16cfffa2
1 file changed
+30 -35
@@ -16,20 +16,12 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
private ulong _lastStatusDivisor; private ulong _lastStatusDivisor;
private bool _useDivisorCycles; private bool _useDivisorCycles;
public readonly struct MontgomeryDivisorData public readonly struct MontgomeryDivisorData(ulong modulus, ulong nPrime, ulong montgomeryOne, ulong montgomeryTwo)
{ {
public readonly ulong Modulus; public readonly ulong Modulus = modulus;
public readonly ulong NPrime; public readonly ulong NPrime = nPrime;
public readonly ulong MontgomeryOne; public readonly ulong MontgomeryOne = montgomeryOne;
public readonly ulong MontgomeryTwo; public readonly ulong MontgomeryTwo = montgomeryTwo;
public MontgomeryDivisorData(ulong modulus, ulong nPrime, ulong montgomeryOne, ulong montgomeryTwo)
{
Modulus = modulus;
NPrime = nPrime;
MontgomeryOne = montgomeryOne;
MontgomeryTwo = montgomeryTwo;
}
} }
private readonly ConcurrentDictionary<Accelerator, Action<Index1D, ulong, ArrayView<MontgomeryDivisorData>, ArrayView<byte>>> _kernelCache = new(); private readonly ConcurrentDictionary<Accelerator, Action<Index1D, ulong, ArrayView<MontgomeryDivisorData>, ArrayView<byte>>> _kernelCache = new();
@@ -64,36 +56,39 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
public bool IsPrime(ulong prime, out bool divisorsExhausted) public bool IsPrime(ulong prime, out bool divisorsExhausted)
{ {
if (!_isConfigured)
{
throw new InvalidOperationException("ConfigureFromMaxPrime must be called before using the tester.");
}
ulong allowedMax = ComputeAllowedMaxDivisor(prime);
if (allowedMax < 3UL)
{
divisorsExhausted = true;
return true;
}
bool composite, coveredRange;
// TODO: Let's rework this to check if the number is prime and check divisors outside of the lock. Lock and update the state afterwards.
lock (_sync) lock (_sync)
{ {
if (!_isConfigured) composite = CheckDivisors(prime, allowedMax, out ulong lastProcessed, out coveredRange);
{
throw new InvalidOperationException("ConfigureFromMaxPrime must be called before using the tester.");
}
ulong allowedMax = ComputeAllowedMaxDivisor(prime);
if (allowedMax < 3UL)
{
divisorsExhausted = true;
return true;
}
bool composite = CheckDivisors(prime, allowedMax, out ulong lastProcessed, out bool coveredRange);
if (lastProcessed != 0UL) if (lastProcessed != 0UL)
{ {
ReportStatus(lastProcessed); ReportStatus(lastProcessed);
} }
if (composite)
{
divisorsExhausted = true;
return false;
}
divisorsExhausted = coveredRange;
return true;
} }
if (composite)
{
divisorsExhausted = true;
return false;
}
divisorsExhausted = coveredRange;
return true;
} }
private bool CheckDivisors(ulong prime, ulong allowedMax, out ulong lastProcessed, out bool coveredRange) private bool CheckDivisors(ulong prime, ulong allowedMax, out ulong lastProcessed, out bool coveredRange)