From 360a31bd546f546df07b2dff2cf1c159517243a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Lema=C5=84czyk?= Date: Mon, 20 Oct 2025 18:37:15 +0200 Subject: [PATCH] Align Lucas-Lehmer GPU helpers with windowed pow2 guidance --- PerfectNumbers.Core/Gpu/GpuUInt128.cs | 14 ++------------ .../Gpu/MersenneNumberLucasLehmerGpuTester.cs | 5 ++--- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/PerfectNumbers.Core/Gpu/GpuUInt128.cs b/PerfectNumbers.Core/Gpu/GpuUInt128.cs index 1158348..af5a386 100644 --- a/PerfectNumbers.Core/Gpu/GpuUInt128.cs +++ b/PerfectNumbers.Core/Gpu/GpuUInt128.cs @@ -1020,18 +1020,8 @@ public struct GpuUInt128 : IComparable, IEquatable [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ulong ShiftLeftByNativeChunk(ulong value, ulong modulus) { - // TODO: Collapse this eight-step shift ladder into the ProcessEightBitWindows helper once it lands so - // we reuse the precomputed window residues instead of emitting `% modulus` after every shift. - value = (value << 1) % modulus; - value = (value << 1) % modulus; - value = (value << 1) % modulus; - value = (value << 1) % modulus; - value = (value << 1) % modulus; - value = (value << 1) % modulus; - value = (value << 1) % modulus; - value = (value << 1) % modulus; - - return value; + // Multiply by 2^NativeModuloChunkBits in one pass so the native-modulo path avoids eight `%` reductions. + return MulMod64(value, 1UL << NativeModuloChunkBits, modulus); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/PerfectNumbers.Core/Gpu/MersenneNumberLucasLehmerGpuTester.cs b/PerfectNumbers.Core/Gpu/MersenneNumberLucasLehmerGpuTester.cs index efac9d3..6da61b2 100644 --- a/PerfectNumbers.Core/Gpu/MersenneNumberLucasLehmerGpuTester.cs +++ b/PerfectNumbers.Core/Gpu/MersenneNumberLucasLehmerGpuTester.cs @@ -112,7 +112,7 @@ public class MersenneNumberLucasLehmerGpuTester var gpu = GpuContextPool.RentPreferred(preferCpu: false); var accelerator = gpu.Accelerator; - var kernel = GetBatchKernel(accelerator); // TODO: Switch this batch path to the ProcessEightBitWindows residue kernel once Lucas–Lehmer integrates the benchmarked windowed pow2 helper for small exponents. + var kernel = GetBatchKernel(accelerator); // Batch kernel already relies on the Mersenne squaring reducer; windowed pow2 helpers do not apply here. var expBuffer = accelerator.Allocate1D(count); ulong[] expArray = ArrayPool.Shared.Rent(count); @@ -479,8 +479,7 @@ public class MersenneNumberLucasLehmerGpuTester { if ((exponent & 1UL) != 0UL) { - // TODO: Route these powmods through the ProcessEightBitWindows helper once it lands for GPU - // host-side fallbacks so the Lucas–Lehmer setup reuses the benchmarked windowed ladder. + // The base varies per primitive-root candidate, so pow2-specific ladders do not apply. result = MulMod(result, value, modulus); }