Merge pull request #80 from mlemanczyk/codex/optimize-evenperfectbitscanner-with-divisor-cycle

Optimize by-divisor cycle usage in GPU testing
This commit is contained in:
Marek Lemańczyk authored and GitHub committed 2025-09-24 22:34:05 +02:00
commit 854e8aaf34
1 file changed
+25 -6
@@ -325,17 +325,27 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
return; return;
} }
ulong exponent = prime;
if (useCycleChecks != 0) if (useCycleChecks != 0)
{ {
ulong cycle = MersenneDivisorCycles.CalculateCycleLengthGpu(modulus); ulong cycle = MersenneDivisorCycles.CalculateCycleLengthGpu(modulus);
if (cycle == 0UL || prime % cycle != 0UL) if (cycle == 0UL)
{ {
hits[index] = 0; hits[index] = 0;
return; return;
} }
ulong remainder = prime % cycle;
if (remainder != 0UL)
{
hits[index] = 0;
return;
} }
hits[index] = prime.Pow2MontgomeryMod(divisor) == 1UL ? (byte)1 : (byte)0; exponent = remainder;
}
hits[index] = exponent.Pow2MontgomeryMod(divisor) == 1UL ? (byte)1 : (byte)0;
} }
public sealed class DivisorScanSession : IDisposable public sealed class DivisorScanSession : IDisposable
@@ -426,7 +436,8 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
return; return;
} }
bool cycleEnabled = owner._useDivisorCycles && divisorCycle != 0UL; ulong cycle = divisorCycle;
bool cycleEnabled = owner._useDivisorCycles && cycle != 0UL;
Accelerator accelerator = _accelerator; Accelerator accelerator = _accelerator;
Action<Index1D, MontgomeryDivisorData, ArrayView<ulong>, ArrayView<ulong>> kernel = _kernel; Action<Index1D, MontgomeryDivisorData, ArrayView<ulong>, ArrayView<ulong>> kernel = _kernel;
@@ -458,7 +469,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
ArrayView1D<ulong, Stride1D.Dense> primeInputView = _resultsBuffer.View.SubView(0, batchSize); ArrayView1D<ulong, Stride1D.Dense> primeInputView = _resultsBuffer.View.SubView(0, batchSize);
primeInputView.CopyFromCPU(ref MemoryMarshal.GetReference(primesSlice), batchSize); primeInputView.CopyFromCPU(ref MemoryMarshal.GetReference(primesSlice), batchSize);
ArrayView1D<byte, Stride1D.Dense> cycleMaskView = cycleMaskViewFull.SubView(0, batchSize); ArrayView1D<byte, Stride1D.Dense> cycleMaskView = cycleMaskViewFull.SubView(0, batchSize);
cycleKernel(batchSize, divisorCycle, primeInputView, cycleMaskView); cycleKernel(batchSize, cycle, primeInputView, cycleMaskView);
accelerator.Synchronize(); accelerator.Synchronize();
cycleMaskView.CopyToCPU(ref MemoryMarshal.GetReference(cycleMaskSpan), batchSize); cycleMaskView.CopyToCPU(ref MemoryMarshal.GetReference(cycleMaskSpan), batchSize);
} }
@@ -486,16 +497,24 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
for (int i = 0; i < computeCount; i++) for (int i = 0; i < computeCount; i++)
{ {
ulong prime = primeSpan[i]; ulong prime = primeSpan[i];
ulong exponentValue;
if (hasDeltaSource) if (hasDeltaSource)
{ {
exponentSlice[i] = prime - currentPrime; exponentValue = prime - currentPrime;
} }
else else
{ {
exponentSlice[i] = prime; exponentValue = prime;
hasDeltaSource = true; hasDeltaSource = true;
} }
if (cycleEnabled)
{
exponentValue %= cycle;
}
exponentSlice[i] = exponentValue;
currentPrime = prime; currentPrime = prime;
} }