MontgomeryDivisorDataPool.Rent / .Return removed as we no longer pool Montgomery divisor data. UInt128Extensions.MontgomeryDivisorDataPool variables optimized.
This commit is contained in:
1 parent
b7773adad8
commit
3c80221105
27 files changed
+260
-476
No files matched your search
@@ -5,20 +5,20 @@ namespace PerfectNumbers.Core.Cpu;
|
||||
|
||||
internal sealed class MersenneCpuDivisorScanSession(PrimeOrderCalculatorAccelerator gpu, ComputationDevice orderDevice) : IMersenneNumberDivisorByDivisorTester.IDivisorScanSession
|
||||
{
|
||||
private Func<ulong, ulong> _getCycleLength = orderDevice switch
|
||||
private Func<ulong, MontgomeryDivisorData, ulong> _getCycleLength = orderDevice switch
|
||||
{
|
||||
ComputationDevice.Gpu => divisor => DivisorCycleCache.Shared.GetCycleLengthGpu(gpu, divisor),
|
||||
ComputationDevice.Hybrid => divisor => DivisorCycleCache.Shared.GetCycleLengthHybrid(gpu, divisor),
|
||||
_ => static (divisor) => DivisorCycleCache.Shared.GetCycleLengthCpu(divisor),
|
||||
ComputationDevice.Gpu => (divisor, divisorData) => DivisorCycleCache.Shared.GetCycleLengthGpu(gpu, divisor, divisorData),
|
||||
ComputationDevice.Hybrid => (divisor, divisorData) => DivisorCycleCache.Shared.GetCycleLengthHybrid(gpu, divisor, divisorData),
|
||||
_ => static (divisor, divisorData) => DivisorCycleCache.Shared.GetCycleLengthCpu(divisor, divisorData),
|
||||
};
|
||||
|
||||
public void Configure(PrimeOrderCalculatorAccelerator gpu, ComputationDevice orderDevice)
|
||||
{
|
||||
_getCycleLength = orderDevice switch
|
||||
{
|
||||
ComputationDevice.Gpu => divisor => DivisorCycleCache.Shared.GetCycleLengthGpu(gpu, divisor),
|
||||
ComputationDevice.Hybrid => divisor => DivisorCycleCache.Shared.GetCycleLengthHybrid(gpu, divisor),
|
||||
_ => static (divisor) => DivisorCycleCache.Shared.GetCycleLengthCpu(divisor),
|
||||
ComputationDevice.Gpu => (divisor, divisorData) => DivisorCycleCache.Shared.GetCycleLengthGpu(gpu, divisor, divisorData),
|
||||
ComputationDevice.Hybrid => (divisor, divisorData) => DivisorCycleCache.Shared.GetCycleLengthHybrid(gpu, divisor, divisorData),
|
||||
_ => static (divisor, divisorData) => DivisorCycleCache.Shared.GetCycleLengthCpu(divisor, divisorData),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ internal sealed class MersenneCpuDivisorScanSession(PrimeOrderCalculatorAccelera
|
||||
|
||||
if (divisorCycle == 0UL)
|
||||
{
|
||||
divisorCycle = _getCycleLength(divisor);
|
||||
divisorCycle = _getCycleLength(divisor, divisorData);
|
||||
// This never kicks off in production code
|
||||
// if (divisorCycle == 0UL)
|
||||
// {
|
||||
|
||||
@@ -6,18 +6,29 @@ using PerfectNumbers.Core.Gpu.Accelerators;
|
||||
|
||||
namespace PerfectNumbers.Core.Cpu;
|
||||
|
||||
public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDivisorByDivisorTester
|
||||
public sealed class MersenneNumberDivisorByDivisorCpuTester(ComputationDevice orderDevice = ComputationDevice.Hybrid) : IMersenneNumberDivisorByDivisorTester
|
||||
{
|
||||
private BigInteger _divisorLimit;
|
||||
private int _batchSize = 1_024;
|
||||
private BigInteger _minK = BigInteger.One;
|
||||
private readonly ComputationDevice _orderDevice;
|
||||
private readonly TryCycleLengthDelegate _tryCalculateCycleLengthForExponent;
|
||||
private readonly CalculateCycleLengthDelegate _calculateCycleLength;
|
||||
private readonly ComputationDevice OrderDevice = orderDevice;
|
||||
private readonly TryCycleLengthDelegate _tryCalculateCycleLengthForExponent = orderDevice switch
|
||||
{
|
||||
ComputationDevice.Gpu => TryCalculateCycleLengthForExponentGpu,
|
||||
ComputationDevice.Hybrid => TryCalculateCycleLengthForExponentHybrid,
|
||||
_ => TryCalculateCycleLengthForExponentCpu,
|
||||
};
|
||||
|
||||
private readonly CalculateCycleLengthDelegate _calculateCycleLength = orderDevice switch
|
||||
{
|
||||
ComputationDevice.Gpu => CalculateCycleLengthGpu,
|
||||
ComputationDevice.Hybrid => CalculateCycleLengthHybrid,
|
||||
_ => CalculateCycleLengthCpu,
|
||||
};
|
||||
|
||||
private string? _stateFilePath;
|
||||
private int _stateCounter;
|
||||
private BigInteger _lastSavedK;
|
||||
public ComputationDevice OrderDevice => _orderDevice;
|
||||
|
||||
private delegate bool TryCycleLengthDelegate(
|
||||
ulong divisor,
|
||||
@@ -43,24 +54,6 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
||||
public GpuUInt128 Limit;
|
||||
}
|
||||
|
||||
public MersenneNumberDivisorByDivisorCpuTester(ComputationDevice orderDevice = ComputationDevice.Hybrid)
|
||||
{
|
||||
_orderDevice = orderDevice;
|
||||
_tryCalculateCycleLengthForExponent = orderDevice switch
|
||||
{
|
||||
ComputationDevice.Gpu => TryCalculateCycleLengthForExponentGpu,
|
||||
ComputationDevice.Hybrid => TryCalculateCycleLengthForExponentHybrid,
|
||||
_ => TryCalculateCycleLengthForExponentCpu,
|
||||
};
|
||||
|
||||
_calculateCycleLength = orderDevice switch
|
||||
{
|
||||
ComputationDevice.Gpu => CalculateCycleLengthGpu,
|
||||
ComputationDevice.Hybrid => CalculateCycleLengthHybrid,
|
||||
_ => CalculateCycleLengthCpu,
|
||||
};
|
||||
}
|
||||
|
||||
public int BatchSize
|
||||
{
|
||||
get => _batchSize;
|
||||
@@ -157,7 +150,7 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public IMersenneNumberDivisorByDivisorTester.IDivisorScanSession CreateDivisorSession(PrimeOrderCalculatorAccelerator gpu) => ThreadStaticPools.RentMersenneCpuDivisorSession(gpu, _orderDevice);
|
||||
public IMersenneNumberDivisorByDivisorTester.IDivisorScanSession CreateDivisorSession(PrimeOrderCalculatorAccelerator gpu) => ThreadStaticPools.RentMersenneCpuDivisorSession(gpu, OrderDevice);
|
||||
|
||||
private bool CheckDivisors(
|
||||
PrimeOrderCalculatorAccelerator gpu,
|
||||
@@ -340,13 +333,12 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
||||
ulong divisorHigh = divisor.High;
|
||||
var residueStepper = new MersenneDivisorResidueStepper(prime, step, divisor);
|
||||
|
||||
var divisorPool = MontgomeryDivisorDataPool.Shared;
|
||||
while (divisor.CompareTo(limit) <= 0)
|
||||
{
|
||||
if (residueStepper.IsAdmissible())
|
||||
{
|
||||
ulong candidate = divisor.Low;
|
||||
MontgomeryDivisorData divisorData = divisorPool.FromModulus(candidate);
|
||||
MontgomeryDivisorData divisorData = MontgomeryDivisorData.FromModulus(candidate);
|
||||
ulong divisorCycle;
|
||||
// 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 (!_tryCalculateCycleLengthForExponent(
|
||||
@@ -370,7 +362,6 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
||||
divisorCycle = computedCycle;
|
||||
}
|
||||
|
||||
divisorPool.Return(divisorData);
|
||||
RecordState(currentK);
|
||||
if (divisorCycle == prime)
|
||||
{
|
||||
@@ -553,12 +544,11 @@ private bool CheckDivisors64(
|
||||
out ulong foundDivisor)
|
||||
{
|
||||
bool canAdvance = step <= limit;
|
||||
FixedCapacityStack<MontgomeryDivisorData> divisorPool = MontgomeryDivisorDataPool.Shared;
|
||||
if (!canAdvance)
|
||||
{
|
||||
if (divisor <= limit && residueStepper.IsAdmissible())
|
||||
{
|
||||
MontgomeryDivisorData divisorData = divisorPool.FromModulus(divisor);
|
||||
MontgomeryDivisorData divisorData = MontgomeryDivisorData.FromModulus(divisor);
|
||||
ulong divisorCycle;
|
||||
if (!_tryCalculateCycleLengthForExponent(
|
||||
divisor,
|
||||
@@ -579,8 +569,6 @@ private bool CheckDivisors64(
|
||||
divisorCycle = computedCycle;
|
||||
}
|
||||
|
||||
divisorPool.Return(divisorData);
|
||||
|
||||
if (divisorCycle == prime)
|
||||
{
|
||||
foundDivisor = divisor;
|
||||
@@ -611,7 +599,7 @@ private bool CheckDivisors64(
|
||||
{
|
||||
if (residueStepper.IsAdmissible())
|
||||
{
|
||||
MontgomeryDivisorData divisorData = divisorPool.FromModulus(divisor);
|
||||
MontgomeryDivisorData divisorData = MontgomeryDivisorData.FromModulus(divisor);
|
||||
ulong divisorCycle;
|
||||
if (!_tryCalculateCycleLengthForExponent(
|
||||
divisor,
|
||||
@@ -632,7 +620,6 @@ private bool CheckDivisors64(
|
||||
divisorCycle = computedCycle;
|
||||
}
|
||||
|
||||
divisorPool.Return(divisorData);
|
||||
RecordState(currentK);
|
||||
if (divisorCycle == prime)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user