Use GpuUInt128 in by-divisor GPU scan
This commit is contained in:
1 parent
cd47b122a5
commit
ea29035c55
2 files changed
+51
-48
No files matched your search
@@ -579,9 +579,6 @@ internal static class Program
|
||||
|
||||
Console.WriteLine("Initialization...");
|
||||
// Compose a results file name that encodes configuration (before opening file)
|
||||
string byDivisorDeltasLabel = mersenneOnGpu
|
||||
? "gpu"
|
||||
: (byDivisorDeltasDevice == ByDivisorDeltasDevice.Gpu ? "cpu-gpu" : "cpu");
|
||||
var builtName = BuildResultsFileName(
|
||||
useBitTransform,
|
||||
threadCount,
|
||||
@@ -591,19 +588,18 @@ internal static class Program
|
||||
useDivisor,
|
||||
useByDivisor,
|
||||
mersenneOnGpu,
|
||||
useOrder,
|
||||
useModuloWorkaround,
|
||||
_useGcdFilter,
|
||||
NttGpuMath.GpuTransformBackend,
|
||||
gpuPrimeThreads,
|
||||
sliceSize,
|
||||
scanBatchSize,
|
||||
_orderWarmupLimitOverride ?? 5_000_000UL,
|
||||
NttGpuMath.ReductionMode,
|
||||
mersenneOnGpu ? "gpu" : "cpu",
|
||||
(GpuContextPool.ForceCpu ? "cpu" : "gpu"),
|
||||
orderOnGpu ? "gpu" : "cpu",
|
||||
byDivisorDeltasLabel);
|
||||
useOrder,
|
||||
useModuloWorkaround,
|
||||
_useGcdFilter,
|
||||
NttGpuMath.GpuTransformBackend,
|
||||
gpuPrimeThreads,
|
||||
sliceSize,
|
||||
scanBatchSize,
|
||||
_orderWarmupLimitOverride ?? 5_000_000UL,
|
||||
NttGpuMath.ReductionMode,
|
||||
mersenneOnGpu ? "gpu" : "cpu",
|
||||
(GpuContextPool.ForceCpu ? "cpu" : "gpu"),
|
||||
orderOnGpu ? "gpu" : "cpu");
|
||||
|
||||
if (!string.IsNullOrEmpty(_resultsPrefix))
|
||||
{
|
||||
@@ -1020,7 +1016,7 @@ internal static class Program
|
||||
Console.WriteLine(" --help, -help, --?, -?, /? show this help message");
|
||||
}
|
||||
|
||||
private static string BuildResultsFileName(bool bitInc, int threads, int block, GpuKernelType kernelType, bool useLucasFlag, bool useDivisorFlag, bool useByDivisorFlag, bool mersenneOnGpu, bool useOrder, bool useModWorkaround, bool useGcd, NttBackend nttBackend, int gpuPrimeThreads, int llSlice, int gpuScanBatch, ulong warmupLimit, ModReductionMode reduction, string mersenneDevice, string primesDevice, string orderDevice, string byDivisorDeltasDevice)
|
||||
private static string BuildResultsFileName(bool bitInc, int threads, int block, GpuKernelType kernelType, bool useLucasFlag, bool useDivisorFlag, bool useByDivisorFlag, bool mersenneOnGpu, bool useOrder, bool useModWorkaround, bool useGcd, NttBackend nttBackend, int gpuPrimeThreads, int llSlice, int gpuScanBatch, ulong warmupLimit, ModReductionMode reduction, string mersenneDevice, string primesDevice, string orderDevice)
|
||||
{
|
||||
string inc = bitInc ? "bit" : "add";
|
||||
string mers = useDivisorFlag
|
||||
@@ -1028,7 +1024,7 @@ internal static class Program
|
||||
: (useLucasFlag
|
||||
? "lucas"
|
||||
: (useByDivisorFlag
|
||||
? $"bydivisor-{byDivisorDeltasDevice}"
|
||||
? "bydivisor"
|
||||
: (kernelType == GpuKernelType.Pow2Mod ? "pow2mod" : "incremental")));
|
||||
string ntt = nttBackend == NttBackend.Staged ? "staged" : "reference";
|
||||
string red = reduction switch { ModReductionMode.Mont64 => "mont64", ModReductionMode.Barrett128 => "barrett128", ModReductionMode.GpuUInt128 => "uint128", _ => "auto" };
|
||||
|
||||
@@ -363,27 +363,24 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt128 step128 = (UInt128)prime << 1;
|
||||
if (step128 == UInt128.Zero)
|
||||
GpuUInt128 step128 = new GpuUInt128(prime);
|
||||
step128.ShiftLeft(1);
|
||||
if (step128.IsZero)
|
||||
{
|
||||
processedAll = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (step128 > ulong.MaxValue)
|
||||
{
|
||||
return CheckDivisorsCpu(prime, allowedMax, out lastProcessed, out processedAll, out processedCount, timeLimit);
|
||||
}
|
||||
|
||||
UInt128 limit = allowedMax;
|
||||
UInt128 divisor128 = step128 + UInt128.One;
|
||||
if (divisor128 > limit)
|
||||
GpuUInt128 limit128 = new GpuUInt128(allowedMax);
|
||||
GpuUInt128 divisor128 = step128;
|
||||
divisor128.Add(1UL);
|
||||
if (divisor128.CompareTo(limit128) > 0)
|
||||
{
|
||||
processedAll = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ulong step = (ulong)step128;
|
||||
ulong step = step128.Low;
|
||||
ulong limit64 = allowedMax;
|
||||
|
||||
int batchCapacity = Math.Max(1, _batchSize);
|
||||
@@ -412,20 +409,27 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
||||
byte step7 = (byte)(step % 7UL);
|
||||
byte step11 = (byte)(step % 11UL);
|
||||
|
||||
byte remainder10 = (byte)((ulong)divisor128 % 10UL);
|
||||
byte remainder8 = (byte)((ulong)divisor128 % 8UL);
|
||||
byte remainder5 = (byte)((ulong)divisor128 % 5UL);
|
||||
byte remainder3 = (byte)((ulong)divisor128 % 3UL);
|
||||
byte remainder7 = (byte)((ulong)divisor128 % 7UL);
|
||||
byte remainder11 = (byte)((ulong)divisor128 % 11UL);
|
||||
ulong startDivisor64 = divisor128.Low;
|
||||
byte remainder10 = (byte)(startDivisor64 % 10UL);
|
||||
byte remainder8 = (byte)(startDivisor64 % 8UL);
|
||||
byte remainder5 = (byte)(startDivisor64 % 5UL);
|
||||
byte remainder3 = (byte)(startDivisor64 % 3UL);
|
||||
byte remainder7 = (byte)(startDivisor64 % 7UL);
|
||||
byte remainder11 = (byte)(startDivisor64 % 11UL);
|
||||
|
||||
bool lastIsSeven = (prime & 3UL) == 3UL;
|
||||
|
||||
try
|
||||
{
|
||||
while (divisor128 <= limit)
|
||||
while (divisor128.CompareTo(limit128) <= 0)
|
||||
{
|
||||
int chunkCount = ComputeChunkCount(divisor128, limit, step128, batchCapacity);
|
||||
if (divisor128.High != 0UL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ulong currentDivisor = divisor128.Low;
|
||||
int chunkCount = ComputeChunkCount(currentDivisor, limit64, step, batchCapacity);
|
||||
if (chunkCount <= 0)
|
||||
{
|
||||
break;
|
||||
@@ -435,7 +439,7 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
||||
Span<byte> maskSpan = maskBuffer.AsSpan(0, chunkCount);
|
||||
|
||||
candidateEvaluator.EvaluateCandidates(
|
||||
(ulong)divisor128,
|
||||
currentDivisor,
|
||||
step,
|
||||
limit64,
|
||||
remainder10,
|
||||
@@ -508,7 +512,10 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
||||
}
|
||||
}
|
||||
|
||||
divisor128 += step128 * (UInt128)chunkCount;
|
||||
GpuUInt128 increment = step128;
|
||||
increment.Mul((ulong)chunkCount);
|
||||
divisor128.Add(increment);
|
||||
|
||||
remainder10 = AdvanceRemainder(remainder10, step10, 10, chunkCount);
|
||||
remainder8 = AdvanceRemainder(remainder8, step8, 8, chunkCount);
|
||||
remainder5 = AdvanceRemainder(remainder5, step5, 5, chunkCount);
|
||||
@@ -524,26 +531,26 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
||||
candidateEvaluator.Dispose();
|
||||
}
|
||||
|
||||
processedAll = divisor128 > limit;
|
||||
processedAll = divisor128.CompareTo(limit128) > 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int ComputeChunkCount(UInt128 currentDivisor, UInt128 limit, UInt128 step, int maxCount)
|
||||
private static int ComputeChunkCount(ulong currentDivisor, ulong limit, ulong step, int maxCount)
|
||||
{
|
||||
if (maxCount <= 0 || step == UInt128.Zero || currentDivisor > limit)
|
||||
if (maxCount <= 0 || step == 0UL || currentDivisor > limit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
UInt128 distance = limit - currentDivisor;
|
||||
UInt128 stepsAvailable = distance / step;
|
||||
UInt128 total = stepsAvailable + UInt128.One;
|
||||
if (total > (UInt128)maxCount)
|
||||
ulong distance = limit - currentDivisor;
|
||||
ulong stepsAvailable = step == 0UL ? 0UL : distance / step;
|
||||
ulong total = stepsAvailable + 1UL;
|
||||
if (total > (ulong)maxCount)
|
||||
{
|
||||
total = (UInt128)maxCount;
|
||||
total = (ulong)maxCount;
|
||||
}
|
||||
|
||||
if (total > (UInt128)int.MaxValue)
|
||||
if (total > (ulong)int.MaxValue)
|
||||
{
|
||||
return int.MaxValue;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user