Various optimizations

This commit is contained in:
mlemanczyk committed 2025-10-29 14:00:38 +01:00
1 parent 3147728d5b
commit 4c79c4087e
9 files changed
+1179 -1229

No files matched your search

+1 -1
View File
@@ -55,7 +55,7 @@ public class ProgramTests
[InlineData(81UL, false)] [InlineData(81UL, false)]
public void IsPrime_identifies_primes_correctly(ulong n, bool expected) public void IsPrime_identifies_primes_correctly(ulong n, bool expected)
{ {
new PrimeTester().IsPrime(n, CancellationToken.None).Should().Be(expected); PrimeTester.IsPrime(n, CancellationToken.None).Should().Be(expected);
} }
[Fact] [Fact]
+1 -1
View File
@@ -622,7 +622,7 @@ internal static class Program
if (!_cliArguments.UseByDivisor) if (!_cliArguments.UseByDivisor)
{ {
if (!(GpuContextPool.ForceCpu if (!(GpuContextPool.ForceCpu
? PrimeTesters.Value!.IsPrime(p, CancellationToken.None) ? PrimeTester.IsPrime(p, CancellationToken.None)
: PrimeTesters.Value!.IsPrimeGpu(p, CancellationToken.None))) : PrimeTesters.Value!.IsPrimeGpu(p, CancellationToken.None)))
{ {
_lastCompositeP = true; _lastCompositeP = true;
@@ -26,7 +26,7 @@ public class PrimeTesterIsPrimeTests
{ {
var tester = new PrimeTester(); var tester = new PrimeTester();
tester.IsPrime(n, CancellationToken.None).Should().Be(expected); PrimeTester.IsPrime(n, CancellationToken.None).Should().Be(expected);
} }
[Theory] [Theory]
+10 -19
View File
@@ -3,7 +3,6 @@ namespace PerfectNumbers.Core.Gpu;
public static class GpuPrimeWorkLimiter public static class GpuPrimeWorkLimiter
{ {
private static SemaphoreSlim _semaphore = new(1, int.MaxValue); private static SemaphoreSlim _semaphore = new(1, int.MaxValue);
private static readonly object _lock = new();
private static int _currentLimit = 1; private static int _currentLimit = 1;
public static Lease Acquire() public static Lease Acquire()
@@ -11,29 +10,21 @@ public static class GpuPrimeWorkLimiter
// TODO: Inline the pooled limiter guard from the GpuLimiterThroughputBenchmarks so prime-sieve // TODO: Inline the pooled limiter guard from the GpuLimiterThroughputBenchmarks so prime-sieve
// GPU jobs stop allocating Lease instances on every acquisition. // GPU jobs stop allocating Lease instances on every acquisition.
var sem = _semaphore; var sem = _semaphore;
sem.Wait(); // sem.Wait();
return new Lease(sem); return new Lease(sem);
} }
public static void SetLimit(int value) public static void SetLimit(int value)
{ {
if (value < 1) if (value == _currentLimit)
{ {
value = 1; return;
} }
lock (_lock) // TODO: Switch to a shared limiter implementation with GpuWorkLimiter so we can coordinate CPU/GPU prime work using
{ // the same semaphore pool without reallocating per adjustment.
if (value == _currentLimit) _semaphore = new SemaphoreSlim(value, value);
{ _currentLimit = value;
return;
}
// TODO: Switch to a shared limiter implementation with GpuWorkLimiter so we can coordinate CPU/GPU prime work using
// the same semaphore pool without reallocating per adjustment.
_semaphore = new SemaphoreSlim(value, value);
_currentLimit = value;
}
} }
public sealed class Lease public sealed class Lease
@@ -47,7 +38,7 @@ public static class GpuPrimeWorkLimiter
public void Dispose() public void Dispose()
{ {
_sem.Release(); // _sem.Release();
} }
} }
} }
@@ -94,7 +94,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
var gpuLease = RentAccelerator(); var gpuLease = RentAccelerator();
var accelerator = gpuLease.Accelerator; var accelerator = gpuLease.Accelerator;
Monitor.Enter(gpuLease.ExecutionLock); // Monitor.Enter(gpuLease.ExecutionLock);
var kernel = GetKernel(accelerator); var kernel = GetKernel(accelerator);
var resources = RentBatchResources(accelerator, batchCapacity); var resources = RentBatchResources(accelerator, batchCapacity);
@@ -121,7 +121,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
out processedCount); out processedCount);
ReturnBatchResources(resources); ReturnBatchResources(resources);
Monitor.Exit(gpuLease.ExecutionLock); // Monitor.Exit(gpuLease.ExecutionLock);
ReturnAccelerator(gpuLease); ReturnAccelerator(gpuLease);
if (composite) if (composite)
@@ -560,7 +560,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
} }
} }
Monitor.Enter(_lease.ExecutionLock); // Monitor.Enter(_lease.ExecutionLock);
EnsureExecutionResourcesLocked(length); EnsureExecutionResourcesLocked(length);
@@ -601,7 +601,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
ref byte hitRef = ref MemoryMarshal.GetReference(hitSlice); ref byte hitRef = ref MemoryMarshal.GetReference(hitSlice);
hitView.CopyToCPU(ref hitRef, length); hitView.CopyToCPU(ref hitRef, length);
Monitor.Exit(_lease.ExecutionLock); // Monitor.Exit(_lease.ExecutionLock);
} }
public void Dispose() public void Dispose()
@@ -30,7 +30,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
var gpuLease = RentAccelerator(); var gpuLease = RentAccelerator();
var accelerator = gpuLease.Accelerator; var accelerator = gpuLease.Accelerator;
Monitor.Enter(gpuLease.ExecutionLock); // Monitor.Enter(gpuLease.ExecutionLock);
var stream = accelerator.CreateStream(); var stream = accelerator.CreateStream();
var kernel = GetPow2ModKernel(accelerator); var kernel = GetPow2ModKernel(accelerator);
@@ -108,7 +108,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
ReturnResources(accelerator, resources); ReturnResources(accelerator, resources);
stream.Dispose(); stream.Dispose();
Monitor.Exit(gpuLease.ExecutionLock); // Monitor.Exit(gpuLease.ExecutionLock);
ReturnAccelerator(gpuLease); ReturnAccelerator(gpuLease);
limiter.Dispose(); limiter.Dispose();
} }
File diff suppressed because it is too large. Load diff
+7 -7
View File
@@ -122,10 +122,10 @@ public sealed class HeuristicPrimeTester
return EvaluateWithOpenNumericFallback(n); return EvaluateWithOpenNumericFallback(n);
} }
if (!UseHeuristicGroupBTrialDivision) // if (!UseHeuristicGroupBTrialDivision)
{ // {
return HeuristicTrialDivisionCpu(n, sqrtLimit, nMod10, includeGroupB: false); // return HeuristicTrialDivisionCpu(n, sqrtLimit, nMod10, includeGroupB: false);
} // }
bool compositeDetected = HeuristicTrialDivisionGpuDetectsDivisor(n, sqrtLimit, nMod10); bool compositeDetected = HeuristicTrialDivisionGpuDetectsDivisor(n, sqrtLimit, nMod10);
return !compositeDetected; return !compositeDetected;
@@ -260,8 +260,8 @@ public sealed class HeuristicPrimeTester
private bool HeuristicTrialDivisionGpuDetectsDivisor(ulong n, ulong sqrtLimit, byte nMod10) private bool HeuristicTrialDivisionGpuDetectsDivisor(ulong n, ulong sqrtLimit, byte nMod10)
{ {
int batchCapacity = Math.Max(1, HeuristicGpuDivisorBatchSize); int batchCapacity = HeuristicGpuDivisorBatchSize;
int interleaveBatchSize = Math.Max(1, HeuristicDivisorInterleaveBatchSize); int interleaveBatchSize = HeuristicDivisorInterleaveBatchSize;
var divisorPool = ThreadStaticPools.UlongPool; var divisorPool = ThreadStaticPools.UlongPool;
var hitPool = ThreadStaticPools.BytePool; var hitPool = ThreadStaticPools.BytePool;
@@ -277,7 +277,7 @@ public sealed class HeuristicPrimeTester
bool compositeDetected = false; bool compositeDetected = false;
int count = 0; int count = 0;
lock (gpu.ExecutionLock) // lock (gpu.ExecutionLock)
{ {
var input = scratch.Input; var input = scratch.Input;
var output = scratch.Output; var output = scratch.Output;
File diff suppressed because it is too large. Load diff