Simplify scheduler configuration and pending composite caching

This commit is contained in:
Marek Lemańczyk committed 2025-10-20 01:07:02 +02:00
1 parent e9cff7bfcd
commit a7ed762428
3 files changed
+23 -48

No files matched your search

@@ -858,13 +858,13 @@ internal static partial class PrimeOrderCalculator
if (currentTimestamp > deadlineTimestamp)
{
pollardRhoDeadlineReached = true;
pending.Add(new PendingEntry(composite, knownComposite: false).WithPrimality(false));
pending.Add(new PendingEntry(composite, knownComposite: true));
continue;
}
if (!TryPollardRho(composite, deadlineTimestamp, out ulong factor))
{
pending.Add(new PendingEntry(composite, knownComposite: false).WithPrimality(false));
pending.Add(new PendingEntry(composite, knownComposite: true));
continue;
}
+4 -4
View File
@@ -1,3 +1,5 @@
using System.Runtime.CompilerServices;
namespace PerfectNumbers.Core;
internal static partial class PrimeOrderCalculator
@@ -14,10 +16,8 @@ internal static partial class PrimeOrderCalculator
public static PrimeOrderSearchConfig HeuristicDefault
{
get
{
return _heuristicDefault;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _heuristicDefault;
}
public static readonly PrimeOrderSearchConfig StrictDefault = new(smallFactorLimit: 1_000_000, pollardRhoMilliseconds: 0, maxPowChecks: 0, PrimeOrderMode.Strict);
+17 -42
View File
@@ -1,31 +1,18 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace PerfectNumbers.Core;
public sealed class UnboundedTaskScheduler : TaskScheduler
{
private static readonly object InstanceLock = new();
private static UnboundedTaskScheduler? _instance;
private static int _configuredThreadCount = Environment.ProcessorCount;
public static UnboundedTaskScheduler Instance
{
get
{
lock (InstanceLock)
{
_instance ??= new UnboundedTaskScheduler(GetNormalizedThreadCount(_configuredThreadCount));
return _instance;
}
}
}
public static UnboundedTaskScheduler Instance => _instance ??= new UnboundedTaskScheduler(_configuredThreadCount);
public static int ConfiguredThreadCount => GetNormalizedThreadCount(Volatile.Read(ref _configuredThreadCount));
public static int ConfiguredThreadCount => _configuredThreadCount;
private readonly object _poolLock = new();
private TaskThreadPool _threadPool;
private UnboundedTaskScheduler(int threadCount)
@@ -35,20 +22,15 @@ public sealed class UnboundedTaskScheduler : TaskScheduler
public static void ConfigureThreadCount(int threadCount)
{
int normalizedThreadCount = GetNormalizedThreadCount(threadCount);
_configuredThreadCount = threadCount;
PrimeOrderCalculator.PrimeOrderSearchConfig.ConfigureHeuristicDefault(threadCount);
lock (InstanceLock)
{
Volatile.Write(ref _configuredThreadCount, normalizedThreadCount);
PrimeOrderCalculator.PrimeOrderSearchConfig.ConfigureHeuristicDefault(normalizedThreadCount);
if (_instance is null)
{
return;
}
_instance.UpdateThreadPool(normalizedThreadCount);
}
// On EvenPerfectBitScanner's execution path the scheduler instance is created after configuration,
// so updating an existing pool would never run. Leave the update path disabled for now.
// if (_instance is not null)
// {
// _instance.UpdateThreadPool(threadCount);
// }
}
public override int MaximumConcurrencyLevel => int.MaxValue;
@@ -60,18 +42,15 @@ public sealed class UnboundedTaskScheduler : TaskScheduler
private void UpdateThreadPool(int threadCount)
{
lock (_poolLock)
if (_threadPool.ThreadCount == threadCount)
{
if (_threadPool.ThreadCount == threadCount)
{
return;
}
TaskThreadPool newPool = new(threadCount, ExecuteTask);
TaskThreadPool oldPool = _threadPool;
_threadPool = newPool;
oldPool.Dispose();
return;
}
TaskThreadPool newPool = new(threadCount, ExecuteTask);
TaskThreadPool oldPool = _threadPool;
_threadPool = newPool;
oldPool.Dispose();
}
private void ExecuteTask(Task task)
@@ -89,8 +68,4 @@ public sealed class UnboundedTaskScheduler : TaskScheduler
return _threadPool.GetScheduledTasks();
}
private static int GetNormalizedThreadCount(int threadCount)
{
return threadCount < 1 ? 1 : threadCount;
}
}