Divisor cycle cache will now respect --divisor-cycles-batch parameter (renamed from --divisor-cycles-batch-size)
This commit is contained in:
1 parent
d7f2dbbec6
commit
8b95a42f27
3 files changed
+23
-18
No files matched your search
@@ -381,7 +381,7 @@ internal static class Program
|
|||||||
{
|
{
|
||||||
useGpuCycles = !arg.AsSpan(arg.IndexOf('=') + 1).Equals("cpu", StringComparison.OrdinalIgnoreCase);
|
useGpuCycles = !arg.AsSpan(arg.IndexOf('=') + 1).Equals("cpu", StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
else if (arg.StartsWith("--divisor-cycles-batch-size=", StringComparison.OrdinalIgnoreCase))
|
else if (arg.StartsWith("--divisor-cycles-batch=", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
cyclesBatchSize = Math.Max(1, int.Parse(arg.AsSpan(arg.IndexOf('=') + 1)));
|
cyclesBatchSize = Math.Max(1, int.Parse(arg.AsSpan(arg.IndexOf('=') + 1)));
|
||||||
}
|
}
|
||||||
@@ -457,6 +457,7 @@ internal static class Program
|
|||||||
MersenneDivisorCycles.Shared.LoadFrom(cyclesPath);
|
MersenneDivisorCycles.Shared.LoadFrom(cyclesPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DivisorCycleCache.SetDivisorCyclesBatchSize(cyclesBatchSize);
|
||||||
DivisorCycleCache.Shared.ConfigureGeneratorDevice(orderOnGpu);
|
DivisorCycleCache.Shared.ConfigureGeneratorDevice(orderOnGpu);
|
||||||
DivisorCycleCache.Shared.ReloadFromCurrentSnapshot();
|
DivisorCycleCache.Shared.ReloadFromCurrentSnapshot();
|
||||||
|
|
||||||
@@ -521,7 +522,7 @@ internal static class Program
|
|||||||
_divisorTester = new MersenneNumberDivisorGpuTester();
|
_divisorTester = new MersenneNumberDivisorGpuTester();
|
||||||
}
|
}
|
||||||
else if (useByDivisor)
|
else if (useByDivisor)
|
||||||
{
|
{
|
||||||
_byDivisorTester = mersenneOnGpu
|
_byDivisorTester = mersenneOnGpu
|
||||||
? new MersenneNumberDivisorByDivisorGpuTester()
|
? new MersenneNumberDivisorByDivisorGpuTester()
|
||||||
: new MersenneNumberDivisorByDivisorCpuTester();
|
: new MersenneNumberDivisorByDivisorCpuTester();
|
||||||
@@ -1313,7 +1314,7 @@ internal static class Program
|
|||||||
Console.WriteLine(" --results-prefix=<text> prefix to prepend to results filename");
|
Console.WriteLine(" --results-prefix=<text> prefix to prepend to results filename");
|
||||||
Console.WriteLine(" --divisor-cycles=<path> divisor cycles data file");
|
Console.WriteLine(" --divisor-cycles=<path> divisor cycles data file");
|
||||||
Console.WriteLine(" --divisor-cycles-device=cpu|gpu device for cycles generation (default gpu)");
|
Console.WriteLine(" --divisor-cycles-device=cpu|gpu device for cycles generation (default gpu)");
|
||||||
Console.WriteLine(" --divisor-cycles-batch-size=<value> batch size for cycles generation (default 512)");
|
Console.WriteLine(" --divisor-cycles-batch=<value> batch size for cycles generation (default 512)");
|
||||||
Console.WriteLine(" --divisor-cycles-continue continue divisor cycles generation");
|
Console.WriteLine(" --divisor-cycles-continue continue divisor cycles generation");
|
||||||
Console.WriteLine(" --divisor-cycles-limit=<value> cycle search iterations when --mersenne=divisor");
|
Console.WriteLine(" --divisor-cycles-limit=<value> cycle search iterations when --mersenne=divisor");
|
||||||
Console.WriteLine(" --use-divisor-cycles=true|false enable divisor cycle filtering in --mersenne=bydivisor (default false)");
|
Console.WriteLine(" --use-divisor-cycles=true|false enable divisor cycle filtering in --mersenne=bydivisor (default false)");
|
||||||
|
|||||||
@@ -24,25 +24,28 @@ public sealed class DivisorCycleCache
|
|||||||
}
|
}
|
||||||
|
|
||||||
private const int CycleGenerationBatchSize = 262_144;
|
private const int CycleGenerationBatchSize = 262_144;
|
||||||
private const int GpuCycleStepsPerInvocation = 524_288 / 16;
|
|
||||||
private const byte ByteZero = 0;
|
private const byte ByteZero = 0;
|
||||||
private const byte ByteOne = 1;
|
private const byte ByteOne = 1;
|
||||||
|
|
||||||
private readonly object _sync = new();
|
private readonly object _sync = new();
|
||||||
private readonly ConcurrentDictionary<int, Task<CycleBlock>> _pending = new();
|
private readonly ConcurrentDictionary<int, Task<CycleBlock>> _pending = new();
|
||||||
private readonly ConcurrentDictionary<Accelerator, Action<Index1D, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>>> _gpuKernelCache = new(AcceleratorReferenceComparer.Instance);
|
private readonly ConcurrentDictionary<Accelerator, Action<Index1D, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>>> _gpuKernelCache = new(AcceleratorReferenceComparer.Instance);
|
||||||
private CycleBlock _baseBlock = null!;
|
private CycleBlock _baseBlock = null!;
|
||||||
private CycleBlock? _activeBlock;
|
private CycleBlock? _activeBlock;
|
||||||
private CycleBlock? _prefetchedBlock;
|
private CycleBlock? _prefetchedBlock;
|
||||||
private bool _useGpuGeneration = true;
|
private bool _useGpuGeneration = true;
|
||||||
|
private readonly int _divisorCyclesBatchSize;
|
||||||
|
private static int _sharedDivisorCyclesBatchSize = GpuConstants.GpuCycleStepsPerInvocation;
|
||||||
|
|
||||||
public static DivisorCycleCache Shared { get; } = new DivisorCycleCache();
|
public static void SetDivisorCyclesBatchSize(int divisorCyclesBatchSize) => _sharedDivisorCyclesBatchSize = divisorCyclesBatchSize;
|
||||||
|
public static DivisorCycleCache Shared { get; } = new DivisorCycleCache(_sharedDivisorCyclesBatchSize);
|
||||||
|
|
||||||
private DivisorCycleCache()
|
private DivisorCycleCache(int divisorCyclesBatchSize)
|
||||||
{
|
{
|
||||||
|
_divisorCyclesBatchSize = divisorCyclesBatchSize;
|
||||||
ulong[] snapshot = MersenneDivisorCycles.Shared.ExportSmallCyclesSnapshot();
|
ulong[] snapshot = MersenneDivisorCycles.Shared.ExportSmallCyclesSnapshot();
|
||||||
Initialize(snapshot);
|
Initialize(snapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReloadFromCurrentSnapshot()
|
public void ReloadFromCurrentSnapshot()
|
||||||
{
|
{
|
||||||
@@ -235,7 +238,7 @@ public sealed class DivisorCycleCache
|
|||||||
|
|
||||||
if (_useGpuGeneration)
|
if (_useGpuGeneration)
|
||||||
{
|
{
|
||||||
ComputeCyclesGpu(start, cycles);
|
ComputeCyclesGpu(start, cycles, _divisorCyclesBatchSize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -277,7 +280,7 @@ public sealed class DivisorCycleCache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ComputeCyclesGpu(ulong start, ulong[] destination)
|
private void ComputeCyclesGpu(ulong start, ulong[] destination, int divisorCyclesBatchSize)
|
||||||
{
|
{
|
||||||
var gpuLease = GpuKernelPool.GetKernel(_useGpuGeneration);
|
var gpuLease = GpuKernelPool.GetKernel(_useGpuGeneration);
|
||||||
var execution = gpuLease.EnterExecutionScope();
|
var execution = gpuLease.EnterExecutionScope();
|
||||||
@@ -285,7 +288,7 @@ public sealed class DivisorCycleCache
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Accelerator accelerator = gpuLease.Accelerator;
|
Accelerator accelerator = gpuLease.Accelerator;
|
||||||
Action<Index1D, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>> kernel = _gpuKernelCache.GetOrAdd(accelerator, LoadKernel);
|
Action<Index1D, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>> kernel = _gpuKernelCache.GetOrAdd(accelerator, LoadKernel);
|
||||||
|
|
||||||
int length = destination.Length;
|
int length = destination.Length;
|
||||||
int chunkCapacity = Math.Min(length, CycleGenerationBatchSize);
|
int chunkCapacity = Math.Min(length, CycleGenerationBatchSize);
|
||||||
@@ -355,7 +358,7 @@ public sealed class DivisorCycleCache
|
|||||||
|
|
||||||
while (pending > 0)
|
while (pending > 0)
|
||||||
{
|
{
|
||||||
kernel(batchSize, divisorView, powView, orderView, resultView, statusView);
|
kernel(batchSize, divisorCyclesBatchSize, divisorView, powView, orderView, resultView, statusView);
|
||||||
accelerator.Synchronize();
|
accelerator.Synchronize();
|
||||||
|
|
||||||
statusView.CopyToCPU(ref MemoryMarshal.GetReference(statusSpan), batchSize);
|
statusView.CopyToCPU(ref MemoryMarshal.GetReference(statusSpan), batchSize);
|
||||||
@@ -390,13 +393,14 @@ public sealed class DivisorCycleCache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Action<Index1D, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>> LoadKernel(Accelerator accelerator)
|
private static Action<Index1D, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>> LoadKernel(Accelerator accelerator)
|
||||||
{
|
{
|
||||||
return accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>>(GpuAdvanceDivisorCyclesKernel);
|
return accelerator.LoadAutoGroupedStreamKernel<Index1D, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>>(GpuAdvanceDivisorCyclesKernel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GpuAdvanceDivisorCyclesKernel(
|
private static void GpuAdvanceDivisorCyclesKernel(
|
||||||
Index1D index,
|
Index1D index,
|
||||||
|
int steps,
|
||||||
ArrayView1D<ulong, Stride1D.Dense> divisors,
|
ArrayView1D<ulong, Stride1D.Dense> divisors,
|
||||||
ArrayView1D<ulong, Stride1D.Dense> pow,
|
ArrayView1D<ulong, Stride1D.Dense> pow,
|
||||||
ArrayView1D<ulong, Stride1D.Dense> order,
|
ArrayView1D<ulong, Stride1D.Dense> order,
|
||||||
@@ -411,7 +415,6 @@ public sealed class DivisorCycleCache
|
|||||||
ulong divisor = divisors[index];
|
ulong divisor = divisors[index];
|
||||||
ulong currentPow = pow[index];
|
ulong currentPow = pow[index];
|
||||||
ulong currentOrder = order[index];
|
ulong currentOrder = order[index];
|
||||||
int steps = GpuCycleStepsPerInvocation;
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
namespace PerfectNumbers.Core.Gpu
|
namespace PerfectNumbers.Core.Gpu
|
||||||
{
|
{
|
||||||
public static class GpuConstants
|
public static class GpuConstants
|
||||||
{
|
{
|
||||||
public const int ScanBatchSize = 2_097_152;
|
public const int ScanBatchSize = 2_097_152;
|
||||||
|
public const int GpuCycleStepsPerInvocation = 256;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user