Merge pull request #71 from mlemanczyk/codex/review-changes-in-mersennenumberdivisorbydivisorgputester.cs

Fix Mod10 shortcut and restore Mod10_8_5_3Steps accuracy
This commit is contained in:
Marek Lemańczyk authored and GitHub committed 2025-09-24 00:32:29 +02:00
commit c1ad705a4a
2 files changed
+30 -27

No files matched your search

@@ -335,43 +335,42 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
MersenneDivisorCycles? divisorCycles = useCycles ? MersenneDivisorCycles.Shared : null;
ulong cycle = useCycles ? divisorCycles!.GetCycle(divisor) : 0UL, primeValue;
MontgomeryDivisorData divisorData = CreateMontgomeryDivisorData(divisor);
Span<ulong> primeSpan = primesHost.AsSpan(0, gpuBatchSize);
ref ulong primesSpanRef = ref MemoryMarshal.GetReference(primeSpan);
Span<int> indexSpan = indexHost.AsSpan(0, gpuBatchSize);
Span<byte> hitsSlice, hitSpan = hitsHost.AsSpan(0, gpuBatchSize);
ref byte hitSpanRef = ref MemoryMarshal.GetReference(hitSpan);
int batchSize, currentSpanSize = gpuBatchSize, gpuCount, i, primesLength = primes.Length;
Span<ulong> primeSpan = Span<ulong>.Empty;
Span<int> indexSpan = Span<int>.Empty;
Span<byte> hitSpan = Span<byte>.Empty;
Span<byte> hitsSlice;
int batchSize, currentSpanSize = -1, gpuCount, i, primesLength = primes.Length;
while (offset < primesLength)
{
batchSize = Math.Min(gpuBatchSize, primesLength - offset);
if (batchSize != currentSpanSize)
{
primeSpan = primesHost.AsSpan(0, batchSize);
primesSpanRef = ref MemoryMarshal.GetReference(primeSpan);
indexSpan = indexHost.AsSpan(0, batchSize);
hitSpan = hitsHost.AsSpan(0, batchSize);
hitSpanRef = ref MemoryMarshal.GetReference(hitSpan);
currentSpanSize = batchSize;
}
// We benefit from the constructor, because CopyTo will be called as static function
primes.Slice(offset, batchSize).CopyTo(primeSpan);
ReadOnlySpan<ulong> primesSlice = primes.Slice(offset, batchSize);
if (++consoleStatus == PerfectNumberConstants.ConsoleInterval)
{
Console.WriteLine($"...processed by-divisor candidate = {primes[0]}");
Console.WriteLine($"...processed by-divisor candidate = {primesSlice[0]}");
consoleStatus = 0;
}
hitsSlice = hits.Slice(offset, batchSize);
gpuCount = 0;
if (useCycles)
{
if (batchSize != currentSpanSize)
{
primeSpan = primesHost.AsSpan(0, batchSize);
indexSpan = indexHost.AsSpan(0, batchSize);
hitSpan = hitsHost.AsSpan(0, batchSize);
currentSpanSize = batchSize;
}
ref ulong primesSpanRef = ref MemoryMarshal.GetReference(primeSpan);
ref byte hitSpanRef = ref MemoryMarshal.GetReference(hitSpan);
gpuCount = 0;
for (i = 0; i < batchSize; i++)
{
primeValue = primeSpan[i];
primeValue = primesSlice[i];
if (cycle == 0UL || primeValue % cycle != 0UL)
{
hitsSlice[i] = 0;
@@ -404,12 +403,12 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
primesView = primesBufferView.SubView(0, batchSize);
hitsView = hitsBufferView.SubView(0, batchSize);
primesView.CopyFromCPU(ref primesSpanRef, batchSize);
ref ulong primesSliceRef = ref MemoryMarshal.GetReference(primesSlice);
primesView.CopyFromCPU(ref primesSliceRef, batchSize);
kernel(batchSize, divisorData, primesView, hitsView);
accelerator.Synchronize();
hitsView.CopyToCPU(ref MemoryMarshal.GetReference(hitSpan), batchSize);
hitSpan.CopyTo(hitsSlice);
hitsView.CopyToCPU(ref MemoryMarshal.GetReference(hitsSlice), batchSize);
}
offset += batchSize;
+7 -3
View File
@@ -85,8 +85,11 @@ public static class ULongExtensions
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong Mod10(this ulong value) => (value & 1UL) == 0UL
? value % 5UL switch
public static ulong Mod10(this ulong value)
{
ulong mod5 = value % 5UL;
return (value & 1UL) == 0UL
? mod5 switch
{
0UL => 0UL,
1UL => 6UL,
@@ -94,7 +97,7 @@ public static class ULongExtensions
3UL => 8UL,
_ => 4UL,
}
: value % 5UL switch
: mod5 switch
{
0UL => 5UL,
1UL => 1UL,
@@ -102,6 +105,7 @@ public static class ULongExtensions
3UL => 3UL,
_ => 9UL,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong Mod128(this ulong value) => value & 127UL;