Add cycle cache hit tracking instrumentation
This commit is contained in:
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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user