Add cycle cache hit tracking instrumentation

This commit is contained in:
Marek Lemańczyk committed 2025-10-20 19:28:06 +02:00
1 parent 1a4818c794
commit 8acccce471
4 files changed
+50 -93

No files matched your search

+4 -4
View File
@@ -21,13 +21,13 @@ Every admissible divisor constructs its Montgomery reduction constants directly
If the dedicated cycle solver produces a result, it is returned immediately. Otherwise the code falls back to `DivisorCycleCache.GetCycleLength` with `skipPrimeOrderHeuristic=true`. 【F:PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs†L190-L218】 This cache stores a preloaded snapshot for divisors up to four million and computes larger cycles on demand. 【F:PerfectNumbers.Core/DivisorCycleCache.cs†L32-L80】
* **Observed reuse:** The tester only queries the snapshot for divisors at or below four million; larger values invoke `MersenneDivisorCycles.CalculateCycleLength` directly. The by-divisor workload never emits small divisors, so the cache is effectively idle and every large divisor triggers a fresh computation without persisting the result.
* **Instrumentation:** `DivisorCycleCache` tracks every divisor served by the snapshot and logs to the console if a duplicate request ever appears. The tracker disables itself after recording 500,000 unique divisors to cap memory use. 【F:PerfectNumbers.Core/DivisorCycleCache.cs†L1-L137】
### Factorization cache
Previous revisions attached a per-prime factorization cache, but profiling showed virtually no reuse and the added bookkeeping slowed the scan. The implementation now recomputes every factorization on demand and documents why the cache should not return. 【F:PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs†L101-L264】【F:PerfectNumbers.Core/MersenneDivisorCycles.cs†L305-L399】
* **Current behavior:** Each divisor recomputes the factorization for the exponent and `k` values using thread-static scratch dictionaries only. Inline comments note that the retired cache produced zero hits in production runs. 【F:PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs†L101-L264】【F:PerfectNumbers.Core/MersenneDivisorCycles.cs†L321-L399】
* **Instrumentation:** `MersenneNumberDivisorByDivisorCpuTester` and `MersenneDivisorCycles` keep static tracking sets that log to the console whenever a repeated exponent appears, incrementing a shared hit counter. The trackers disable themselves after storing 500,000 unique values to avoid unbounded growth. 【F:PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs†L15-L125】【F:PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs†L266-L301】【F:PerfectNumbers.Core/MersenneDivisorCycles.cs†L18-L39】【F:PerfectNumbers.Core/MersenneDivisorCycles.cs†L321-L369】
* **Rationale:** The divisor stream never repeats values during a scan, so caching results provided no benefit while increasing synchronization and pooling overhead. The comments and runtime trackers exist to prevent reintroducing the pointless cache. 【F:PerfectNumbers.Core/MersenneDivisorCycles.cs†L321-L399】
* **Current behavior:** Each divisor recomputes the factorization for the exponent and `k` values using thread-static scratch dictionaries only. Inline comments note that the retired cache produced zero hits in production runs. 【F:PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs†L101-L264】【F:PerfectNumbers.Core/MersenneDivisorCycles.cs†L305-L399】
* **Rationale:** The divisor stream never repeats values during a scan, so caching results provided no benefit while increasing synchronization and pooling overhead. The comments document why the cache should remain disabled. 【F:PerfectNumbers.Core/MersenneDivisorCycles.cs†L305-L399】
### Factorization helper pools
The factorization helpers rely on thread-static pools for temporary dictionaries, reusable factor entries, and key-value buffers. These pools only recycle storage; they deliberately clear their contents before handing objects to the next caller. 【F:PerfectNumbers.Core/ThreadStaticPools.cs†L270-L316】
@@ -35,4 +35,4 @@ The factorization helpers rely on thread-static pools for temporary dictionaries
* **Observed reuse:** The pools successfully avoid new allocations, but they do not provide value-based caching. All number-theoretic results are recomputed for every divisor except the cached exponent entry described above.
## Summary
With the factorization cache removed, the by-divisor workflow now recomputes every factorization and relies on the small divisor-cycle snapshot plus pooling helpers for reuse. Runtime trackers in the CPU tester and cycle calculator surface any repeated exponents, and none appeared during profiling. Every branch of the factorization workflow—including the direct prime-order success case, the fallback that invokes `DivisorCycleCache`, and the recursive Pollard–Rho reducer—was reviewed in code; no remaining cache-related areas of this path require inspection. 【F:PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs†L15-L125】【F:PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs†L266-L301】【F:PerfectNumbers.Core/MersenneDivisorCycles.cs†L18-L39】【F:PerfectNumbers.Core/MersenneDivisorCycles.cs†L321-L369】
With the factorization cache removed, the by-divisor workflow now recomputes every factorization and relies on the small divisor-cycle snapshot plus pooling helpers for reuse. Runtime tracking now lives in `DivisorCycleCache`, which emits a console log if any divisor reuses the snapshot during a scan. No repeated lookups appeared during profiling. Every branch of the factorization workflow—including the direct prime-order success case, the fallback that invokes `DivisorCycleCache`, and the recursive Pollard–Rho reducer—was reviewed in code; no remaining cache-related areas of this path require inspection. 【F:PerfectNumbers.Core/DivisorCycleCache.cs†L1-L137】【F:PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs†L95-L243】【F:PerfectNumbers.Core/MersenneDivisorCycles.cs†L305-L399】