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

@@ -12,12 +12,6 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
private ulong _lastStatusDivisor;
private int _batchSize = 1_024;
private const int FactorCachePrimeTrackingLimit = 500_000;
private static readonly HashSet<ulong> FactorCacheTrackedPrimes = new();
private static readonly object FactorCachePrimeLock = new();
private static ulong FactorCachePrimeHitCount;
private static bool FactorCachePrimeTrackingDisabled;
[ThreadStatic]
private static GpuUInt128WorkSet _divisorScanGpuWorkSet;
@@ -122,8 +116,6 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
processedCount = 0UL;
processedAll = false;
ObserveFactorCachePrime(prime);
// The EvenPerfectBitScanner feeds primes >= 138,000,000 here, so allowedMax >= 3 in production runs.
// Keeping the guard commented out documents the reasoning for benchmarks and tests.
// if (allowedMax < 3UL)
@@ -263,43 +255,6 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
return false;
}
private static void ObserveFactorCachePrime(ulong prime)
{
bool logHit = false;
ulong hitNumber = 0UL;
bool trackingDisabledNow = false;
lock (FactorCachePrimeLock)
{
if (FactorCachePrimeTrackingDisabled)
{
return;
}
if (!FactorCacheTrackedPrimes.Add(prime))
{
FactorCachePrimeHitCount++;
hitNumber = FactorCachePrimeHitCount;
logHit = true;
}
else if (FactorCacheTrackedPrimes.Count >= FactorCachePrimeTrackingLimit)
{
FactorCachePrimeTrackingDisabled = true;
FactorCacheTrackedPrimes.Clear();
trackingDisabledNow = true;
}
}
if (logHit)
{
Console.WriteLine($"Factor cache hit for exponent {prime} ({hitNumber})");
}
else if (trackingDisabledNow)
{
Console.WriteLine("Factor cache hit tracking disabled after exceeding the tracking limit.");
}
}
private static byte CheckDivisor(ulong prime, ulong divisorCycle, in MontgomeryDivisorData divisorData)
{
ulong residue = prime.Pow2MontgomeryModWithCycleCpu(divisorCycle, divisorData);
+46
View File
@@ -1,5 +1,6 @@
using System.Buffers;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ILGPU;
@@ -20,6 +21,12 @@ public sealed class DivisorCycleCache
private readonly int _divisorCyclesBatchSize;
private static int _sharedDivisorCyclesBatchSize = GpuConstants.GpuCycleStepsPerInvocation;
private const int CycleCacheTrackingLimit = 500_000;
private static readonly HashSet<ulong> CycleCacheTrackedDivisors = new();
private static readonly object CycleCacheTrackingLock = new();
private static ulong CycleCacheHitCount;
private static bool CycleCacheTrackingDisabled;
public static void SetDivisorCyclesBatchSize(int divisorCyclesBatchSize)
{
_sharedDivisorCyclesBatchSize = Math.Max(1, divisorCyclesBatchSize);
@@ -72,6 +79,7 @@ public sealed class DivisorCycleCache
throw new InvalidDataException($"Divisor cycle is missing for {divisor}");
}
ObserveCycleCacheDivisor(divisor);
return cached;
}
@@ -106,6 +114,7 @@ public sealed class DivisorCycleCache
throw new InvalidDataException($"Divisor cycle is missing for {divisor}");
}
ObserveCycleCacheDivisor(divisor);
cycles[i] = cached;
}
else
@@ -133,6 +142,43 @@ public sealed class DivisorCycleCache
}
}
private static void ObserveCycleCacheDivisor(ulong divisor)
{
bool logHit = false;
ulong hitNumber = 0UL;
bool trackingDisabledNow = false;
lock (CycleCacheTrackingLock)
{
if (CycleCacheTrackingDisabled)
{
return;
}
if (!CycleCacheTrackedDivisors.Add(divisor))
{
CycleCacheHitCount++;
hitNumber = CycleCacheHitCount;
logHit = true;
}
else if (CycleCacheTrackedDivisors.Count >= CycleCacheTrackingLimit)
{
CycleCacheTrackingDisabled = true;
CycleCacheTrackedDivisors.Clear();
trackingDisabledNow = true;
}
}
if (logHit)
{
Console.WriteLine($"Cycle cache hit for divisor {divisor} ({hitNumber})");
}
else if (trackingDisabledNow)
{
Console.WriteLine("Cycle cache hit tracking disabled after exceeding the tracking limit.");
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ComputeCyclesCpu(ReadOnlySpan<ulong> divisors, Span<ulong> cycles, ReadOnlySpan<int> indices)
{
@@ -15,12 +15,6 @@ public class MersenneDivisorCycles
private List<(ulong divisor, ulong cycleLength)> _table = [];
// Lightweight read-mostly cache for small divisors (<= 4,000,000). 0 => unknown
private ulong[]? _smallCycles;
private const int FactorCacheExponentTrackingLimit = 500_000;
private static readonly HashSet<ulong> FactorCacheTrackedExponents = new();
private static readonly object FactorCacheTrackingLock = new();
private static ulong FactorCacheHitCount;
private static bool FactorCacheTrackingDisabled;
public static MersenneDivisorCycles Shared { get; } = new MersenneDivisorCycles();
public MersenneDivisorCycles()
@@ -318,7 +312,6 @@ public class MersenneDivisorCycles
factorCounts[2UL] = twoCount;
}
ObserveFactorCacheExponent(exponent);
bool exponentAccumulated = AccumulateFactors(exponent, factorCounts);
bool factorsAccumulated = exponentAccumulated && AccumulateFactors(k, factorCounts);
@@ -333,43 +326,6 @@ public class MersenneDivisorCycles
return success;
}
private static void ObserveFactorCacheExponent(ulong exponent)
{
bool logHit = false;
ulong hitNumber = 0UL;
bool trackingDisabledNow = false;
lock (FactorCacheTrackingLock)
{
if (FactorCacheTrackingDisabled)
{
return;
}
if (!FactorCacheTrackedExponents.Add(exponent))
{
FactorCacheHitCount++;
hitNumber = FactorCacheHitCount;
logHit = true;
}
else if (FactorCacheTrackedExponents.Count >= FactorCacheExponentTrackingLimit)
{
FactorCacheTrackingDisabled = true;
FactorCacheTrackedExponents.Clear();
trackingDisabledNow = true;
}
}
if (logHit)
{
Console.WriteLine($"Factor cache hit for exponent {exponent} ({hitNumber})");
}
else if (trackingDisabledNow)
{
Console.WriteLine("Factor cache hit tracking disabled after exceeding the tracking limit.");
}
}
private static bool AccumulateFactors(
ulong value,
Dictionary<ulong, int> counts)