Kernels made part of the accelerators for better performance.

This commit is contained in:
mlemanczyk committed 2025-11-13 18:52:46 +01:00
1 parent 0d2a88c45f
commit be435b7760
5 files changed
+29 -53

No files matched your search

@@ -104,22 +104,7 @@ internal sealed class HeuristicPrimeTesterAccelerator
return cached; return cached;
} }
[ThreadStatic] public readonly Kernel HeuristicTrialDivisionKernel;
public static Dictionary<Accelerator, Action<AcceleratorStream, Index1D, ArrayView<int>, ulong, ulong, HeuristicGpuDivisorTableKind, HeuristicGpuDivisorTables>>? HeuristicTrialDivisionKernel;
internal static Action<AcceleratorStream, Index1D, ArrayView<int>, ulong, ulong, HeuristicGpuDivisorTableKind, HeuristicGpuDivisorTables> GetHeuristicTrialDivisionKernel(Accelerator accelerator)
{
var pool = HeuristicTrialDivisionKernel ??= [];
if (pool.TryGetValue(accelerator, out var cached))
{
return cached;
}
cached = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<int>, ulong, ulong, HeuristicGpuDivisorTableKind, HeuristicGpuDivisorTables>(PrimeTesterKernels.HeuristicTrialDivisionKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView<int>, ulong, ulong, HeuristicGpuDivisorTableKind, HeuristicGpuDivisorTables>>();
pool[accelerator] = cached;
return cached;
}
public MemoryBuffer1D<ulong, Stride1D.Dense> Input = null!; public MemoryBuffer1D<ulong, Stride1D.Dense> Input = null!;
public MemoryBuffer1D<byte, Stride1D.Dense> Output = null!; public MemoryBuffer1D<byte, Stride1D.Dense> Output = null!;
@@ -152,17 +137,19 @@ internal sealed class HeuristicPrimeTesterAccelerator
Context = accelerator.Context; Context = accelerator.Context;
Accelerator = accelerator; Accelerator = accelerator;
AcceleratorStream stream = accelerator.CreateStream(); EnsureCapacity(minBufferCapacity);
// var kernels = _kernels[index]; //GpuKernelPool.Kernels;
HeuristicTrialDivisionKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<int>, ulong, ulong, HeuristicGpuDivisorTableKind, HeuristicGpuDivisorTables>(PrimeTesterKernels.HeuristicTrialDivisionKernel));
AcceleratorStream stream = AcceleratorStreamPool.Rent(accelerator);
// GpuStaticTableInitializer.EnsureStaticTables(accelerator, kernels, stream); // GpuStaticTableInitializer.EnsureStaticTables(accelerator, kernels, stream);
_sharedTables = Accelerators.HeuristicGpuTables.EnsureStaticTables(accelerator, stream); _sharedTables = Accelerators.HeuristicGpuTables.EnsureStaticTables(accelerator, stream);
var heuristicDivisorTables = _sharedTables.CreateHeuristicDivisorTables(); _heuristicDivisorTables = _sharedTables.CreateHeuristicDivisorTables();
_heuristicDivisorTables = heuristicDivisorTables;
EnsureCapacity(minBufferCapacity);
stream.Synchronize(); stream.Synchronize();
stream.Dispose(); AcceleratorStreamPool.Return(stream);
} }
public void EnsureCapacity(int minCapacity) public void EnsureCapacity(int minCapacity)
@@ -172,16 +159,13 @@ internal sealed class HeuristicPrimeTesterAccelerator
return; return;
} }
Input?.Dispose(); Input.Dispose();
Output?.Dispose(); Output.Dispose();
HeuristicFlag?.Dispose(); HeuristicFlag?.Dispose();
// lock (Accelerator) Input = Accelerator.Allocate1D<ulong>(minCapacity);
{ Output = Accelerator.Allocate1D<byte>(minCapacity);
Input = Accelerator.Allocate1D<ulong>(minCapacity); HeuristicFlag = Accelerator.Allocate1D<int>(minCapacity);
Output = Accelerator.Allocate1D<byte>(minCapacity);
HeuristicFlag = Accelerator.Allocate1D<int>(minCapacity);
}
BufferCapacity = minCapacity; BufferCapacity = minCapacity;
} }
@@ -110,6 +110,8 @@ public sealed class PrimeOrderCalculatorAccelerator
public readonly Kernel ConvertToStandardKernel; public readonly Kernel ConvertToStandardKernel;
public readonly Kernel KeepMontgomeryKernel; public readonly Kernel KeepMontgomeryKernel;
public readonly Kernel PollardRhoKernel; public readonly Kernel PollardRhoKernel;
public Kernel SharesFactorKernel;
public void EnsureCapacity(int factorsCount, int primeTesterCapacity) public void EnsureCapacity(int factorsCount, int primeTesterCapacity)
{ {
@@ -199,6 +201,8 @@ public sealed class PrimeOrderCalculatorAccelerator
SmallPrimeSieveKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SmallPrimeSieveKernel)); SmallPrimeSieveKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SmallPrimeSieveKernel));
PollardRhoKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<ulong, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.TryPollardRhoKernel)); PollardRhoKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<ulong, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.TryPollardRhoKernel));
SharesFactorKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SharesFactorKernel)); ;
} }
public void Dispose() public void Dispose()
@@ -228,7 +228,7 @@ public sealed class HeuristicCombinedPrimeTester
var gpu = HeuristicPrimeTesterAccelerator.Rent(1); var gpu = HeuristicPrimeTesterAccelerator.Rent(1);
var accelerator = gpu.Accelerator; var accelerator = gpu.Accelerator;
var stream = gpu.Stream; var stream = gpu.Stream;
var kernel = HeuristicPrimeTesterAccelerator.HeuristicTrialDivisionKernel; var kernel = gpu.HeuristicTrialDivisionKernel;
var flagView1D = gpu.HeuristicFlag.View; var flagView1D = gpu.HeuristicFlag.View;
var flagView = flagView1D.AsContiguous(); var flagView = flagView1D.AsContiguous();
@@ -240,8 +240,9 @@ public sealed class HeuristicCombinedPrimeTester
stream!.Synchronize(); stream!.Synchronize();
kernel( kernel.Launch(
stream, stream,
1,
divisorLength, divisorLength,
flagView, flagView,
n, n,
+6 -5
View File
@@ -243,9 +243,8 @@ public sealed class HeuristicPrimeTester
{ {
// GpuPrimeWorkLimiter.Acquire(); // GpuPrimeWorkLimiter.Acquire();
var gpu = HeuristicPrimeTesterAccelerator.Rent(1); var gpu = HeuristicPrimeTesterAccelerator.Rent(1);
var accelerator = gpu.Accelerator;
var stream = gpu.Stream; var stream = gpu.Stream;
var kernel = HeuristicPrimeTesterAccelerator.GetHeuristicTrialDivisionKernel(accelerator); var kernel = gpu.HeuristicTrialDivisionKernel;
var flagView1D = gpu.HeuristicFlag.View; var flagView1D = gpu.HeuristicFlag.View;
var flagView = flagView1D.AsContiguous(); var flagView = flagView1D.AsContiguous();
@@ -255,8 +254,9 @@ public sealed class HeuristicPrimeTester
int groupALength = HeuristicPrimeSieves.GroupADivisors.Length; int groupALength = HeuristicPrimeSieves.GroupADivisors.Length;
flagView1D.CopyFromCPU(stream, ref compositeFlag, 1); flagView1D.CopyFromCPU(stream, ref compositeFlag, 1);
kernel( kernel.Launch(
stream!, stream!,
1,
groupALength, groupALength,
flagView, flagView,
n, n,
@@ -292,8 +292,9 @@ public sealed class HeuristicPrimeTester
compositeFlag = 0; compositeFlag = 0;
flagView1D.CopyFromCPU(stream, ref compositeFlag, 1); flagView1D.CopyFromCPU(stream, ref compositeFlag, 1);
kernel( kernel.Launch(
stream, stream,
1,
divisorLength, divisorLength,
flagView, flagView,
n, n,
+2 -16
View File
@@ -278,10 +278,10 @@ public sealed class PrimeTester
// and implement it. // and implement it.
int length = values.Length; int length = values.Length;
ArrayPool<ulong> pool = ThreadStaticPools.UlongPool;
var gpu = PrimeOrderCalculatorAccelerator.Rent(1); var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
var accelerator = gpu.Accelerator; var accelerator = gpu.Accelerator;
var kernel = gpu.SharesFactorKernel;
gpu.EnsureCapacity(0, length); gpu.EnsureCapacity(0, length);
MemoryBuffer1D<ulong, Stride1D.Dense>? inputBuffer = gpu.PrimeTestInput; MemoryBuffer1D<ulong, Stride1D.Dense>? inputBuffer = gpu.PrimeTestInput;
MemoryBuffer1D<byte, Stride1D.Dense>? resultBuffer = gpu.OutputByte; MemoryBuffer1D<byte, Stride1D.Dense>? resultBuffer = gpu.OutputByte;
@@ -289,8 +289,7 @@ public sealed class PrimeTester
AcceleratorStream stream = AcceleratorStreamPool.Rent(accelerator); AcceleratorStream stream = AcceleratorStreamPool.Rent(accelerator);
inputBuffer.View.CopyFromCPU(stream, values); inputBuffer.View.CopyFromCPU(stream, values);
var kernel = GetSharesFactorKernel(accelerator); kernel.Launch(stream, 1, length, inputBuffer.View, resultBuffer.View);
kernel(stream, length, inputBuffer.View, resultBuffer.View);
resultBuffer.View.CopyToCPU(stream, in results); resultBuffer.View.CopyToCPU(stream, in results);
stream.Synchronize(); stream.Synchronize();
@@ -298,19 +297,6 @@ public sealed class PrimeTester
PrimeOrderCalculatorAccelerator.Return(gpu); PrimeOrderCalculatorAccelerator.Return(gpu);
} }
private static Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<byte>> GetSharesFactorKernel(Accelerator accelerator)
{
var pool = _kernel ?? [];
if (pool.TryGetValue(accelerator, out var cached))
{
return cached;
}
cached = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SharesFactorKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<byte>>>();
pool[accelerator] = cached;
return cached;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong BinaryGcd(ulong u, ulong v) private static ulong BinaryGcd(ulong u, ulong v)
{ {