From 5dd9eb636d6f0de65cebb186bb40f856504d0654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Lema=C5=84czyk?= Date: Tue, 21 Oct 2025 21:19:57 +0200 Subject: [PATCH] Inline GPU divisor locking adjustments --- ...MersenneNumberDivisorByDivisorGpuTester.cs | 93 +++++++++++-------- 1 file changed, 53 insertions(+), 40 deletions(-) diff --git a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs index 5868edc..84f3644 100644 --- a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs +++ b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs @@ -2,6 +2,7 @@ using System.Buffers; using System.Collections.Concurrent; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Threading; using ILGPU; using ILGPU.Runtime; @@ -96,42 +97,41 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv var gpuLease = GpuContextPool.RentPreferred(preferCpu: false); var accelerator = gpuLease.Accelerator; - var kernel = GetKernel(accelerator); - BatchResources resources = RentBatchResources(accelerator, batchCapacity); - try - { - composite = CheckDivisors( - prime, - allowedMax, - accelerator, - kernel, - resources.DivisorsBuffer, - resources.ExponentBuffer, - resources.HitsBuffer, - resources.DivisorDeltaBuffer, - resources.RemainderDeltaBuffer, - resources.RemainderBuffer, - resources.RemainderDeltaKernel, - resources.RemainderScanKernel, - resources.CandidateMaskKernel, - resources.Divisors, - resources.Exponents, - resources.Hits, - resources.DivisorData, - resources.CycleCandidates, - resources.CycleLengths, - resources.CycleCapacity, - out lastProcessed, - out coveredRange, - out processedCount - ); - } - finally - { - ReturnBatchResources(accelerator, resources); - gpuLease.Dispose(); - } + Monitor.Enter(gpuLease.ExecutionLock); + + var kernel = GetKernel(accelerator); + var resources = RentBatchResources(accelerator, batchCapacity); + + composite = CheckDivisors( + prime, + allowedMax, + accelerator, + kernel, + resources.DivisorsBuffer, + resources.ExponentBuffer, + resources.HitsBuffer, + resources.DivisorDeltaBuffer, + resources.RemainderDeltaBuffer, + resources.RemainderBuffer, + resources.RemainderDeltaKernel, + resources.RemainderScanKernel, + resources.CandidateMaskKernel, + resources.Divisors, + resources.Exponents, + resources.Hits, + resources.DivisorData, + resources.CycleCandidates, + resources.CycleLengths, + resources.CycleCapacity, + out lastProcessed, + out coveredRange, + out processedCount + ); + + ReturnBatchResources(accelerator, resources); + Monitor.Exit(gpuLease.ExecutionLock); + gpuLease.Dispose(); if (composite) { @@ -540,7 +540,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv private readonly MersenneNumberDivisorByDivisorGpuTester _owner; private readonly GpuContextPool.GpuContextLease _lease; private readonly Accelerator _accelerator; - private readonly Action, ArrayView> _kernel; + private Action, ArrayView> _kernel; private MemoryBuffer1D _exponentsBuffer; private MemoryBuffer1D _resultsBuffer; private ulong[] _hostBuffer; @@ -552,11 +552,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv _owner = owner; _lease = GpuContextPool.RentPreferred(preferCpu: false); _accelerator = _lease.Accelerator; - _kernel = owner.GetKernelByPrimeExponent(_accelerator); _capacity = Math.Max(1, owner._gpuBatchSize); - _exponentsBuffer = _accelerator.Allocate1D(_capacity); - _resultsBuffer = _accelerator.Allocate1D(_capacity); - _hostBuffer = ArrayPool.Shared.Rent(_capacity); } internal void Reset() @@ -564,6 +560,14 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv _disposed = false; } + private void EnsureExecutionResourcesLocked() + { + _kernel = _owner.GetKernelByPrimeExponent(_accelerator); + _exponentsBuffer = _accelerator.Allocate1D(_capacity); + _resultsBuffer = _accelerator.Allocate1D(_capacity); + _hostBuffer = ArrayPool.Shared.Rent(_capacity); + } + public void CheckDivisor(ulong divisor, in MontgomeryDivisorData divisorData, ulong divisorCycle, in ReadOnlySpan primes, Span hits) { if (_disposed) @@ -583,6 +587,13 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv return; } + Monitor.Enter(_lease.ExecutionLock); + + if (_kernel == null) + { + EnsureExecutionResourcesLocked(); + } + ArrayView1D exponentsView = _exponentsBuffer.View; ArrayView1D resultsView = _resultsBuffer.View; Span hostSpan = _hostBuffer.AsSpan(0, _capacity); @@ -609,6 +620,8 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv offset += batchSize; } + + Monitor.Exit(_lease.ExecutionLock); } public void Dispose()