Remove GPU context creation lock
This commit is contained in:
1 parent
c39a99a4fd
commit
de7ddd8db3
10 files changed
+11
-71
No files matched your search
@@ -227,7 +227,6 @@ public sealed class DivisorCycleCache
|
||||
{
|
||||
int length = divisors.Length;
|
||||
var gpuLease = GpuKernelPool.GetKernel(useGpuOrder: true);
|
||||
var execution = gpuLease.EnterExecutionScope();
|
||||
|
||||
Accelerator accelerator = gpuLease.Accelerator;
|
||||
var kernel = _gpuKernelCache.GetOrAdd(accelerator, LoadKernel);
|
||||
@@ -309,7 +308,6 @@ public sealed class DivisorCycleCache
|
||||
ArrayPool<byte>.Shared.Return(rentedStatus!, clearArray: false);
|
||||
}
|
||||
|
||||
execution.Dispose();
|
||||
gpuLease.Dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@ public static class GpuContextPool
|
||||
|
||||
private static readonly ConcurrentQueue<PooledContext> CpuPool = new();
|
||||
private static readonly ConcurrentQueue<PooledContext> GpuPool = new();
|
||||
private static readonly object CreationLock = new();
|
||||
|
||||
public static GpuContextLease Rent()
|
||||
{
|
||||
@@ -61,20 +60,17 @@ public static class GpuContextPool
|
||||
{
|
||||
if (preferCpu && CpuPool.TryDequeue(out var cpu))
|
||||
{
|
||||
return new GpuContextLease(cpu, CreationLock);
|
||||
return new GpuContextLease(cpu);
|
||||
}
|
||||
|
||||
if (!preferCpu && GpuPool.TryDequeue(out var gpu))
|
||||
{
|
||||
return new GpuContextLease(gpu, CreationLock);
|
||||
return new GpuContextLease(gpu);
|
||||
}
|
||||
}
|
||||
|
||||
// Serialize accelerator creation to avoid concurrent CL device/stream setup across threads.
|
||||
lock (CreationLock)
|
||||
{
|
||||
return new GpuContextLease(new PooledContext(preferCpu), CreationLock);
|
||||
}
|
||||
// Create a new accelerator when the pool does not have one available.
|
||||
return new GpuContextLease(new PooledContext(preferCpu));
|
||||
}
|
||||
|
||||
public static void DisposeAll()
|
||||
@@ -113,30 +109,24 @@ public static class GpuContextPool
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
lock (CreationLock)
|
||||
{
|
||||
ctx.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct GpuContextLease
|
||||
{
|
||||
private readonly PooledContext _ctx;
|
||||
|
||||
internal GpuContextLease(PooledContext ctx, object kernelInitLock)
|
||||
internal GpuContextLease(PooledContext ctx)
|
||||
{
|
||||
_ctx = ctx;
|
||||
KernelInitLock = kernelInitLock;
|
||||
}
|
||||
|
||||
public Context Context => _ctx.Context;
|
||||
|
||||
public Accelerator Accelerator => _ctx.Accelerator;
|
||||
|
||||
public object KernelInitLock { get; }
|
||||
|
||||
public object ExecutionLock => _ctx.ExecutionLock;
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ public sealed class GpuKernelLease
|
||||
private GpuContextLease? _gpu;
|
||||
private KernelContainer? _kernels;
|
||||
private AcceleratorStream? _stream;
|
||||
private object? _executionLock;
|
||||
|
||||
private GpuKernelLease()
|
||||
{
|
||||
@@ -31,7 +30,6 @@ public sealed class GpuKernelLease
|
||||
lease._gpu = gpu;
|
||||
lease._kernels = kernels;
|
||||
lease._stream = null;
|
||||
lease._executionLock = gpu.ExecutionLock;
|
||||
return lease;
|
||||
}
|
||||
|
||||
@@ -53,14 +51,12 @@ public sealed class GpuKernelLease
|
||||
}
|
||||
}
|
||||
|
||||
public ExecutionScope EnterExecutionScope() => new ExecutionScope(_executionLock);
|
||||
|
||||
public Action<AcceleratorStream, Index1D, ulong, ulong, ArrayView<GpuUInt128>, ArrayView<ulong>> OrderKernel
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator; // avoid capturing 'this' in lambda
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
lock (_gpu!.Value.ExecutionLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.Order, () =>
|
||||
{
|
||||
@@ -77,7 +73,7 @@ public sealed class GpuKernelLease
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
lock (_gpu!.Value.ExecutionLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.Pow2Mod, () =>
|
||||
{
|
||||
@@ -94,7 +90,7 @@ public sealed class GpuKernelLease
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
lock (_gpu!.Value.ExecutionLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.Incremental, () =>
|
||||
{
|
||||
@@ -111,7 +107,7 @@ public sealed class GpuKernelLease
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
lock (_gpu!.Value.ExecutionLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.IncrementalOrder, () =>
|
||||
{
|
||||
@@ -128,7 +124,7 @@ public sealed class GpuKernelLease
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
lock (_gpu!.Value.ExecutionLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.Pow2ModOrder, () =>
|
||||
{
|
||||
@@ -145,7 +141,7 @@ public sealed class GpuKernelLease
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
lock (_gpu!.Value.ExecutionLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.SmallPrimeFactor, () =>
|
||||
{
|
||||
@@ -165,8 +161,6 @@ public sealed class GpuKernelLease
|
||||
_gpu?.Dispose();
|
||||
_gpu = null;
|
||||
|
||||
_executionLock = null;
|
||||
|
||||
_releaseLimiter?.Invoke();
|
||||
_releaseLimiter = null;
|
||||
|
||||
@@ -174,25 +168,4 @@ public sealed class GpuKernelLease
|
||||
Pool.Enqueue(this);
|
||||
}
|
||||
|
||||
public readonly struct ExecutionScope
|
||||
{
|
||||
private readonly object? _lock;
|
||||
|
||||
public ExecutionScope(object? sync)
|
||||
{
|
||||
_lock = sync;
|
||||
if (_lock is not null)
|
||||
{
|
||||
Monitor.Enter(_lock);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_lock is not null)
|
||||
{
|
||||
Monitor.Exit(_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,12 +293,10 @@ public class GpuKernelPool
|
||||
public static void Run(Action<Accelerator, AcceleratorStream> action)
|
||||
{
|
||||
var lease = GetKernel(useGpuOrder: true);
|
||||
var execution = lease.EnterExecutionScope();
|
||||
var accelerator = lease.Accelerator;
|
||||
var stream = accelerator.CreateStream();
|
||||
action(accelerator, stream);
|
||||
stream.Dispose();
|
||||
execution.Dispose();
|
||||
lease.Dispose();
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ public class MersenneNumberIncrementalGpuTester(GpuKernelType kernelType, bool u
|
||||
throw new NotImplementedException($"GPU incremental scanning requires the device cycle heuristics implementation (kernel: {_kernelType}, GPU order: {_useGpuOrder}).");
|
||||
|
||||
var gpuLease = GpuKernelPool.GetKernel(_useGpuOrder);
|
||||
var execution = gpuLease.EnterExecutionScope();
|
||||
var accelerator = gpuLease.Accelerator;
|
||||
var stream = gpuLease.Stream;
|
||||
int batchSize = GpuConstants.ScanBatchSize; // large batch improves GPU occupancy
|
||||
@@ -123,7 +122,6 @@ public class MersenneNumberIncrementalGpuTester(GpuKernelType kernelType, bool u
|
||||
|
||||
ArrayPool<ulong>.Shared.Return(orderArray);
|
||||
orderBuffer.Dispose();
|
||||
execution.Dispose();
|
||||
gpuLease.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ public class MersenneNumberOrderGpuTester(GpuKernelType kernelType, bool useGpuO
|
||||
public void Scan(ulong exponent, UInt128 twoP, LastDigit lastDigit, UInt128 maxK, ref bool isPrime)
|
||||
{
|
||||
var gpuLease = GpuKernelPool.GetKernel(_useGpuOrder);
|
||||
var execution = gpuLease.EnterExecutionScope();
|
||||
var accelerator = gpuLease.Accelerator;
|
||||
var stream = gpuLease.Stream;
|
||||
int batchSize = GpuConstants.ScanBatchSize; // large batch improves GPU occupancy and avoids TDR
|
||||
@@ -61,7 +60,6 @@ public class MersenneNumberOrderGpuTester(GpuKernelType kernelType, bool useGpuO
|
||||
}
|
||||
|
||||
foundBuffer.Dispose();
|
||||
execution.Dispose();
|
||||
gpuLease.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -194,7 +194,6 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
try
|
||||
{
|
||||
var lease = GpuKernelPool.GetKernel(useGpuOrder: true);
|
||||
var execution = lease.EnterExecutionScope();
|
||||
Accelerator accelerator = lease.Accelerator;
|
||||
AcceleratorStream stream = lease.Stream;
|
||||
|
||||
@@ -248,7 +247,6 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
countBuffer.Dispose();
|
||||
remainingBuffer.Dispose();
|
||||
fullyFactoredBuffer.Dispose();
|
||||
execution.Dispose();
|
||||
lease.Dispose();
|
||||
return true;
|
||||
}
|
||||
@@ -362,7 +360,6 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
order = 0UL;
|
||||
|
||||
var lease = GpuKernelPool.GetKernel(useGpuOrder: true);
|
||||
var execution = lease.EnterExecutionScope();
|
||||
Accelerator accelerator = lease.Accelerator;
|
||||
AcceleratorStream stream = lease.Stream;
|
||||
|
||||
@@ -467,7 +464,6 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
stackProductBuffer.Dispose();
|
||||
resultBuffer.Dispose();
|
||||
statusBuffer.Dispose();
|
||||
execution.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -526,7 +522,6 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
private static bool TryComputeOnGpu(ReadOnlySpan<ulong> exponents, ulong prime, in MontgomeryDivisorData divisorData, Span<ulong> results)
|
||||
{
|
||||
var lease = GpuKernelPool.GetKernel(useGpuOrder: true);
|
||||
var execution = lease.EnterExecutionScope();
|
||||
Accelerator accelerator = lease.Accelerator;
|
||||
AcceleratorStream stream = lease.Stream;
|
||||
var kernel = GetPow2ModKernel(accelerator);
|
||||
@@ -551,7 +546,6 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
Console.WriteLine($"Exception for {prime} and exponents: {string.Join(",", exponents.ToArray())}.");
|
||||
exponentBuffer.Dispose();
|
||||
remainderBuffer.Dispose();
|
||||
execution.Dispose();
|
||||
lease.Dispose();
|
||||
throw;
|
||||
}
|
||||
@@ -559,7 +553,6 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
remainderBuffer.View.CopyToCPU(ref MemoryMarshal.GetReference(results), exponents.Length);
|
||||
exponentBuffer.Dispose();
|
||||
remainderBuffer.Dispose();
|
||||
execution.Dispose();
|
||||
lease.Dispose();
|
||||
return true;
|
||||
}
|
||||
@@ -587,7 +580,6 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
|
||||
try
|
||||
{
|
||||
var execution = lease.EnterExecutionScope();
|
||||
Accelerator accelerator = lease.Accelerator;
|
||||
AcceleratorStream stream = lease.Stream;
|
||||
var kernel = GetPow2ModWideKernel(accelerator);
|
||||
@@ -628,7 +620,6 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
|
||||
exponentBuffer.Dispose();
|
||||
remainderBuffer.Dispose();
|
||||
execution.Dispose();
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
|
||||
@@ -147,7 +147,6 @@ public sealed class MersenneNumberTester(
|
||||
UInt128[] qs = qsBuffer;
|
||||
|
||||
var gpuLease = GpuKernelPool.GetKernel(_useGpuOrder);
|
||||
var execution = gpuLease.EnterExecutionScope();
|
||||
var accelerator = gpuLease.Accelerator;
|
||||
var stream = gpuLease.Stream;
|
||||
var orderKernel = gpuLease.OrderKernel!;
|
||||
@@ -194,7 +193,6 @@ public sealed class MersenneNumberTester(
|
||||
qBuffer.Dispose();
|
||||
}
|
||||
|
||||
execution.Dispose();
|
||||
gpuLease.Dispose();
|
||||
ArrayPool<UInt128>.Shared.Return(qs);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ internal static partial class PrimeOrderCalculator
|
||||
remaining = value;
|
||||
|
||||
var lease = GpuKernelPool.GetKernel(useGpuOrder: true);
|
||||
var execution = lease.EnterExecutionScope();
|
||||
Accelerator accelerator = lease.Accelerator;
|
||||
AcceleratorStream stream = lease.Stream;
|
||||
|
||||
@@ -64,7 +63,6 @@ internal static partial class PrimeOrderCalculator
|
||||
counts.Add(primeValue, exponent);
|
||||
}
|
||||
|
||||
execution.Dispose();
|
||||
lease.Dispose();
|
||||
ThreadStaticPools.UlongPool.Return(primeBufferArray);
|
||||
ThreadStaticPools.IntPool.Return(exponentBufferArray);
|
||||
|
||||
@@ -417,7 +417,6 @@ public static partial class ULongExtensions
|
||||
ulong result = 0UL;
|
||||
|
||||
GpuKernelLease lease = GpuKernelPool.GetKernel(useGpuOrder: true);
|
||||
var execution = lease.EnterExecutionScope();
|
||||
|
||||
Accelerator accelerator = lease.Accelerator;
|
||||
// Keep this commented out. It should never happen in production code.
|
||||
@@ -444,7 +443,6 @@ public static partial class ULongExtensions
|
||||
|
||||
resultBuffer.Dispose();
|
||||
exponentBuffer.Dispose();
|
||||
execution.Dispose();
|
||||
lease.Dispose();
|
||||
// Keep this commented. We don't want to catch any exceptions. All should crash the scanner.
|
||||
// catch (AcceleratorException)
|
||||
|
||||
Reference in new issue
Block a user