From cd69c08fb43fd5e63823d351eeeeca8a4402486f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Lema=C5=84czyk?= Date: Sat, 11 Oct 2025 20:50:13 +0200 Subject: [PATCH] Remove Montgomery divisor cache --- ...MersenneNumberDivisorByDivisorCpuTester.cs | 28 +++++++++++++++++-- ...MersenneNumberDivisorByDivisorGpuTester.cs | 1 - PerfectNumbers.Core/MontgomeryDivisorData.cs | 28 ------------------- 3 files changed, 26 insertions(+), 31 deletions(-) diff --git a/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs b/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs index f5862af..d4d74cd 100644 --- a/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs +++ b/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs @@ -192,6 +192,10 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv Dictionary? factorCache = null; DivisorCycleCache cycleCache = DivisorCycleCache.Shared; + ulong cachedModulus = 0UL; + MontgomeryDivisorData cachedDivisorData = default; + bool hasCachedDivisorData = false; + byte step10 = (byte)(step % 10UL); byte step8 = (byte)(step % 8UL); byte step5 = (byte)(step % 5UL); @@ -222,7 +226,14 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv if (admissible && (remainder8 == 1 || remainder8 == 7) && remainder3 != 0 && remainder5 != 0 && remainder7 != 0 && remainder11 != 0) { - MontgomeryDivisorData divisorData = MontgomeryDivisorDataCache.Get(candidate); + if (!hasCachedDivisorData || cachedModulus != candidate) + { + cachedDivisorData = MontgomeryDivisorData.FromModulus(candidate); + cachedModulus = candidate; + hasCachedDivisorData = true; + } + + MontgomeryDivisorData divisorData = cachedDivisorData; ulong divisorCycle; if (candidate <= PerfectNumberConstants.MaxQForDivisorCycles) @@ -340,6 +351,9 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv { private readonly MersenneNumberDivisorByDivisorCpuTester _owner; private bool _disposed; + private bool _hasCachedDivisorData; + private ulong _cachedDivisor; + private MontgomeryDivisorData _cachedDivisorData; internal DivisorScanSession(MersenneNumberDivisorByDivisorCpuTester owner) { @@ -349,6 +363,9 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv internal void Reset() { _disposed = false; + _hasCachedDivisorData = false; + _cachedDivisor = 0UL; + _cachedDivisorData = default; } public void CheckDivisor(ulong divisor, in MontgomeryDivisorData divisorData, ulong divisorCycle, ReadOnlySpan primes, Span hits) @@ -367,7 +384,14 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv MontgomeryDivisorData cachedData = divisorData; if (cachedData.Modulus != divisor) { - cachedData = MontgomeryDivisorDataCache.Get(divisor); + if (!_hasCachedDivisorData || _cachedDivisor != divisor) + { + _cachedDivisorData = MontgomeryDivisorData.FromModulus(divisor); + _cachedDivisor = divisor; + _hasCachedDivisorData = true; + } + + cachedData = _cachedDivisorData; } if (divisorCycle == 0UL) diff --git a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs index 2220711..a67ce8f 100644 --- a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs +++ b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs @@ -7,7 +7,6 @@ using System.Numerics; using ILGPU; using ILGPU.Runtime; using MontgomeryDivisorData = PerfectNumbers.Core.MontgomeryDivisorData; -using MontgomeryDivisorDataCache = PerfectNumbers.Core.MontgomeryDivisorDataCache; using CycleRemainderStepper = PerfectNumbers.Core.CycleRemainderStepper; namespace PerfectNumbers.Core.Gpu; diff --git a/PerfectNumbers.Core/MontgomeryDivisorData.cs b/PerfectNumbers.Core/MontgomeryDivisorData.cs index 348471b..187e921 100644 --- a/PerfectNumbers.Core/MontgomeryDivisorData.cs +++ b/PerfectNumbers.Core/MontgomeryDivisorData.cs @@ -45,32 +45,4 @@ public readonly struct MontgomeryDivisorData(ulong modulus, ulong nPrime, ulong montgomeryTwo, montgomeryTwoSquared); } - -} - -internal static class MontgomeryDivisorDataCache -{ - [ThreadStatic] - private static bool s_hasCachedValue; - - [ThreadStatic] - private static ulong s_cachedModulus; - - [ThreadStatic] - private static MontgomeryDivisorData s_cachedData; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static MontgomeryDivisorData Get(ulong modulus) - { - if (s_hasCachedValue && s_cachedModulus == modulus) - { - return s_cachedData; - } - - MontgomeryDivisorData computed = MontgomeryDivisorData.FromModulus(modulus); - s_cachedModulus = modulus; - s_cachedData = computed; - s_hasCachedValue = true; - return computed; - } }