Gate GPU by-divisor scans to a single accelerator
This commit is contained in:
1 parent
6b1c2d0665
commit
3735a1cf0f
1 file changed
+53
-5
@@ -26,6 +26,11 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
private readonly ConcurrentDictionary<Accelerator, Action<Index1D, ArrayView<GpuDivisorPartialData>, ArrayView<int>, ArrayView<int>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>, ArrayView<int>>> _kernelCache = new(AcceleratorReferenceComparer.Instance);
|
private readonly ConcurrentDictionary<Accelerator, Action<Index1D, ArrayView<GpuDivisorPartialData>, ArrayView<int>, ArrayView<int>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>, ArrayView<int>>> _kernelCache = new(AcceleratorReferenceComparer.Instance);
|
||||||
private readonly ConcurrentDictionary<Accelerator, ConcurrentBag<BatchResources>> _resourcePools = new(AcceleratorReferenceComparer.Instance);
|
private readonly ConcurrentDictionary<Accelerator, ConcurrentBag<BatchResources>> _resourcePools = new(AcceleratorReferenceComparer.Instance);
|
||||||
private readonly ConcurrentBag<GpuContextPool.GpuContextLease> _acceleratorPool = new();
|
private readonly ConcurrentBag<GpuContextPool.GpuContextLease> _acceleratorPool = new();
|
||||||
|
private readonly SemaphoreSlim _acceleratorAvailable = new(0);
|
||||||
|
private int _createdAccelerators;
|
||||||
|
// Limit GPU context concurrency to avoid replicating the large batch buffers across thousands of worker threads.
|
||||||
|
private int _acceleratorLimit = 1;
|
||||||
|
private int _waitingAcceleratorCount;
|
||||||
private readonly ConcurrentBag<DivisorScanSession> _sessionPool = new();
|
private readonly ConcurrentBag<DivisorScanSession> _sessionPool = new();
|
||||||
|
|
||||||
private Action<Index1D, ArrayView<GpuDivisorPartialData>, ArrayView<int>, ArrayView<int>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>, ArrayView<int>> GetKernel(Accelerator accelerator) =>
|
private Action<Index1D, ArrayView<GpuDivisorPartialData>, ArrayView<int>, ArrayView<int>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>, ArrayView<int>> GetKernel(Accelerator accelerator) =>
|
||||||
@@ -679,15 +684,58 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
|
|
||||||
private GpuContextPool.GpuContextLease RentAccelerator()
|
private GpuContextPool.GpuContextLease RentAccelerator()
|
||||||
{
|
{
|
||||||
if (_acceleratorPool.TryTake(out var lease))
|
while (true)
|
||||||
{
|
{
|
||||||
return lease;
|
if (_acceleratorPool.TryTake(out var lease))
|
||||||
}
|
{
|
||||||
|
return lease;
|
||||||
|
}
|
||||||
|
|
||||||
return GpuContextPool.RentPreferred(preferCpu: false);
|
if (TryCreateAccelerator(out lease))
|
||||||
|
{
|
||||||
|
return lease;
|
||||||
|
}
|
||||||
|
|
||||||
|
Interlocked.Increment(ref _waitingAcceleratorCount);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_acceleratorAvailable.Wait();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Interlocked.Decrement(ref _waitingAcceleratorCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReturnAccelerator(GpuContextPool.GpuContextLease lease) => _acceleratorPool.Add(lease);
|
private bool TryCreateAccelerator(out GpuContextPool.GpuContextLease lease)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int created = Volatile.Read(ref _createdAccelerators);
|
||||||
|
int limit = Volatile.Read(ref _acceleratorLimit);
|
||||||
|
if (created >= limit)
|
||||||
|
{
|
||||||
|
lease = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Interlocked.CompareExchange(ref _createdAccelerators, created + 1, created) == created)
|
||||||
|
{
|
||||||
|
lease = GpuContextPool.RentPreferred(preferCpu: false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReturnAccelerator(GpuContextPool.GpuContextLease lease)
|
||||||
|
{
|
||||||
|
_acceleratorPool.Add(lease);
|
||||||
|
if (Volatile.Read(ref _waitingAcceleratorCount) > 0)
|
||||||
|
{
|
||||||
|
_acceleratorAvailable.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private BatchResources RentBatchResources(Accelerator accelerator, int capacity)
|
private BatchResources RentBatchResources(Accelerator accelerator, int capacity)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user