PrimeOrderCalculatorAccelerator.Rent is now created outside of the loops and re-used for all calculations.
This commit is contained in:
1 parent
57a50e2a37
commit
b9ca95bf8c
53 files changed
+4639
-4229
No files matched your search
@@ -1,10 +1,12 @@
|
||||
using PerfectNumbers.Core.Gpu.Accelerators;
|
||||
|
||||
namespace PerfectNumbers.Core.Cpu;
|
||||
|
||||
public class MersenneNumberOrderCpuTester(GpuKernelType kernelType)
|
||||
{
|
||||
private readonly GpuKernelType _kernelType = kernelType;
|
||||
|
||||
public void Scan(ulong exponent, UInt128 twoP, LastDigit lastDigit, UInt128 maxK, ref bool isPrime)
|
||||
public void Scan(PrimeOrderCalculatorAccelerator gpu, ulong exponent, UInt128 twoP, LastDigit lastDigit, UInt128 maxK, ref bool isPrime)
|
||||
{
|
||||
UInt128 k = 1UL;
|
||||
var auto = new MersenneResidueAutomaton(exponent);
|
||||
@@ -13,10 +15,10 @@ public class MersenneNumberOrderCpuTester(GpuKernelType kernelType)
|
||||
|
||||
while (k <= maxK && Volatile.Read(ref isPrime))
|
||||
{
|
||||
qCycle = MersenneDivisorCycles.GetCycle(q);
|
||||
// TODO: When this lookup misses the snapshot, invoke the configured device to compute the
|
||||
// single required cycle on demand without persisting it so the CPU order path retains the
|
||||
// cycle-stepping speedups while honoring the no-extra-cache constraint for large divisors.
|
||||
qCycle = MersenneDivisorCycles.GetCycle(gpu, q);
|
||||
// TODO: When this lookup misses the snapshot, invoke the configured device to compute the
|
||||
// single required cycle on demand without persisting it so the CPU order path retains the
|
||||
// cycle-stepping speedups while honoring the no-extra-cache constraint for large divisors.
|
||||
int allowMask2 = lastDigit == LastDigit.Seven ? CpuConstants.LastSevenMask10 : CpuConstants.LastOneMask10;
|
||||
bool shouldCheck = ((allowMask2 >> (int)auto.Mod10R) & 1) != 0;
|
||||
if (shouldCheck)
|
||||
@@ -33,33 +35,33 @@ public class MersenneNumberOrderCpuTester(GpuKernelType kernelType)
|
||||
}
|
||||
if (shouldCheck)
|
||||
{
|
||||
if (_kernelType == GpuKernelType.Pow2Mod)
|
||||
{
|
||||
if (exponent.PowModWithCycle(q, qCycle) == 1UL)
|
||||
{
|
||||
Volatile.Write(ref isPrime, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt128 phi = q - 1UL;
|
||||
if (phi <= ulong.MaxValue)
|
||||
{
|
||||
ulong phi64 = (ulong)phi;
|
||||
if (phi64.PowModWithCycle(q, qCycle) == 1UL)
|
||||
{
|
||||
UInt128 halfPow = (phi64 >> 1).PowModWithCycle(q, qCycle) - 1UL;
|
||||
if (halfPow.BinaryGcd(q) == 1UL)
|
||||
{
|
||||
ulong divMul = (ulong)((((UInt128)1 << 64) - 1UL) / exponent) + 1UL;
|
||||
ulong div = phi64.FastDiv64(exponent, divMul);
|
||||
UInt128 divPow = div.PowModWithCycle(q, qCycle) - 1UL;
|
||||
if (divPow.BinaryGcd(q) == 1UL)
|
||||
{
|
||||
Volatile.Write(ref isPrime, false);
|
||||
break;
|
||||
}
|
||||
if (_kernelType == GpuKernelType.Pow2Mod)
|
||||
{
|
||||
if (exponent.PowModWithCycle(q, qCycle) == 1UL)
|
||||
{
|
||||
Volatile.Write(ref isPrime, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt128 phi = q - 1UL;
|
||||
if (phi <= ulong.MaxValue)
|
||||
{
|
||||
ulong phi64 = (ulong)phi;
|
||||
if (phi64.PowModWithCycle(q, qCycle) == 1UL)
|
||||
{
|
||||
UInt128 halfPow = (phi64 >> 1).PowModWithCycle(q, qCycle) - 1UL;
|
||||
if (halfPow.BinaryGcd(q) == 1UL)
|
||||
{
|
||||
ulong divMul = (ulong)((((UInt128)1 << 64) - 1UL) / exponent) + 1UL;
|
||||
ulong div = phi64.FastDiv64(exponent, divMul);
|
||||
UInt128 divPow = div.PowModWithCycle(q, qCycle) - 1UL;
|
||||
if (divPow.BinaryGcd(q) == 1UL)
|
||||
{
|
||||
Volatile.Write(ref isPrime, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,7 +72,7 @@ public class MersenneNumberOrderCpuTester(GpuKernelType kernelType)
|
||||
auto.Next();
|
||||
q = auto.CurrentQ();
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user