Merge pull request #241 from mlemanczyk/codex/remove-executionscope-structure
Remove GPU context creation lock
This commit is contained in:
10 files changed
+5
-83
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,15 +51,11 @@ 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)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.Order, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<Index1D, ulong, ulong, ArrayView<GpuUInt128>, ArrayView<ulong>>(OrderKernels.OrderKernelScan);
|
||||
@@ -70,15 +64,12 @@ public sealed class GpuKernelLease
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> Pow2ModKernel
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.Pow2Mod, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2ModKernels.Pow2ModKernelScan);
|
||||
@@ -87,15 +78,12 @@ public sealed class GpuKernelLease
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ulong, ulong, ulong, ulong, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>> IncrementalKernel
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.Incremental, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ulong, ulong, ulong, ulong, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>>(IncrementalKernels.IncrementalKernelScan);
|
||||
@@ -104,15 +92,12 @@ public sealed class GpuKernelLease
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>> IncrementalOrderKernel
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.IncrementalOrder, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>>(IncrementalKernels.IncrementalOrderKernelScan);
|
||||
@@ -121,15 +106,12 @@ public sealed class GpuKernelLease
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>> Pow2ModOrderKernel
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.Pow2ModOrder, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2ModKernels.Pow2ModOrderKernelScan);
|
||||
@@ -138,15 +120,12 @@ public sealed class GpuKernelLease
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> SmallPrimeFactorKernel
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels!.SmallPrimeFactor, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(SmallPrimeFactorKernels.SmallPrimeFactorKernelScan);
|
||||
@@ -155,7 +134,6 @@ public sealed class GpuKernelLease
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -165,8 +143,6 @@ public sealed class GpuKernelLease
|
||||
_gpu?.Dispose();
|
||||
_gpu = null;
|
||||
|
||||
_executionLock = null;
|
||||
|
||||
_releaseLimiter?.Invoke();
|
||||
_releaseLimiter = null;
|
||||
|
||||
@@ -174,25 +150,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