Use atomic flag writes in heuristic trial division

This commit is contained in:
Marek Lemańczyk committed 2025-10-29 20:40:40 +01:00
1 parent 5ac05489c1
commit f9504a6a19
4 files changed
+19 -22

No files matched your search

@@ -68,18 +68,10 @@ internal static class PrimeTesterKernels
results[index] = result;
}
public static void HeuristicTrialDivisionKernel(Index1D index, ArrayView<ulong> divisors, ulong n, ArrayView<byte> resultFlag)
public static void HeuristicTrialDivisionKernel(Index1D index, ArrayView<ulong> divisors, ulong n, ArrayView<int> resultFlag)
{
ulong divisor = divisors[index];
if (divisor <= 1UL)
{
return;
}
if (n % divisor == 0UL)
{
resultFlag[0] = 1;
}
Atomic.Or(ref resultFlag[0], divisor <= 1UL ? 0 : (n % divisor == 0UL ? 1 : 0));
}
public static void SharesFactorKernel(Index1D index, ArrayView<ulong> numbers, ArrayView<byte> results)
@@ -221,16 +221,16 @@ public sealed class HeuristicCombinedPrimeTester
int count = 0;
var inputView = gpu.Input.View;
var outputView = gpu.Output.View;
var flagView = gpu.HeuristicFlag.View;
bool ProcessBatch(int length)
{
inputView.CopyFromCPU(ref divisorArray[0], length);
byte compositeFlag = 0;
outputView.CopyFromCPU(ref compositeFlag, 1);
kernel(length, inputView, n, outputView);
int compositeFlag = 0;
flagView.CopyFromCPU(ref compositeFlag, 1);
kernel(length, inputView, n, flagView);
accelerator.Synchronize();
outputView.CopyToCPU(ref compositeFlag, 1);
flagView.CopyToCPU(ref compositeFlag, 1);
return compositeFlag != 0;
}
+5 -5
View File
@@ -279,7 +279,7 @@ public sealed class HeuristicPrimeTester
int count = 0;
var inputView = gpu.Input.View;
var outputView = gpu.Output.View;
var flagView = gpu.HeuristicFlag.View;
bool ProcessBatch(int length)
{
@@ -289,11 +289,11 @@ public sealed class HeuristicPrimeTester
}
inputView.CopyFromCPU(ref divisorArray[0], length);
byte compositeFlag = 0;
outputView.CopyFromCPU(ref compositeFlag, 1);
kernel(length, inputView, n, outputView);
int compositeFlag = 0;
flagView.CopyFromCPU(ref compositeFlag, 1);
kernel(length, inputView, n, flagView);
accelerator.Synchronize();
outputView.CopyToCPU(ref compositeFlag, 1);
flagView.CopyToCPU(ref compositeFlag, 1);
return compositeFlag != 0;
}
+7 -2
View File
@@ -272,7 +272,7 @@ public static bool IsPrimeCpu(ulong n, CancellationToken ct)
internal readonly Context AcceleratorContext;
public readonly Accelerator Accelerator;
public readonly Action<Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>> Kernel;
public readonly Action<Index1D, ArrayView<ulong>, ulong, ArrayView<byte>> HeuristicTrialDivisionKernel;
public readonly Action<Index1D, ArrayView<ulong>, ulong, ArrayView<int>> HeuristicTrialDivisionKernel;
public readonly MemoryBuffer1D<uint, Stride1D.Dense> DevicePrimesDefault;
public readonly MemoryBuffer1D<uint, Stride1D.Dense> DevicePrimesLastOne;
public readonly MemoryBuffer1D<uint, Stride1D.Dense> DevicePrimesLastSeven;
@@ -285,6 +285,7 @@ public static bool IsPrimeCpu(ulong n, CancellationToken ct)
public readonly MemoryBuffer1D<ulong, Stride1D.Dense> DevicePrimesPow2LastNine;
public MemoryBuffer1D<ulong, Stride1D.Dense> Input;
public MemoryBuffer1D<byte, Stride1D.Dense> Output;
public MemoryBuffer1D<int, Stride1D.Dense> HeuristicFlag;
public int BufferCapacity;
internal PrimeTesterGpuContextLease(int minBufferCapacity)
@@ -292,7 +293,7 @@ public static bool IsPrimeCpu(ulong n, CancellationToken ct)
AcceleratorContext = Context.CreateDefault();
Accelerator = AcceleratorContext.GetPreferredDevice(false).CreateAccelerator(AcceleratorContext);
Kernel = Accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SmallPrimeSieveKernel);
HeuristicTrialDivisionKernel = Accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ulong, ArrayView<byte>>(PrimeTesterKernels.HeuristicTrialDivisionKernel);
HeuristicTrialDivisionKernel = Accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ulong, ArrayView<int>>(PrimeTesterKernels.HeuristicTrialDivisionKernel);
var primesDefault = DivisorGenerator.SmallPrimes;
DevicePrimesDefault = Accelerator.Allocate1D<uint>(primesDefault.Length);
@@ -337,6 +338,7 @@ public static bool IsPrimeCpu(ulong n, CancellationToken ct)
BufferCapacity = minBufferCapacity < 1 ? 1 : minBufferCapacity;
Input = Accelerator.Allocate1D<ulong>(BufferCapacity);
Output = Accelerator.Allocate1D<byte>(BufferCapacity);
HeuristicFlag = Accelerator.Allocate1D<int>(BufferCapacity);
_returned = false;
}
@@ -350,8 +352,10 @@ public static bool IsPrimeCpu(ulong n, CancellationToken ct)
Input.Dispose();
Output.Dispose();
HeuristicFlag.Dispose();
Input = Accelerator.Allocate1D<ulong>(required);
Output = Accelerator.Allocate1D<byte>(required);
HeuristicFlag = Accelerator.Allocate1D<int>(required);
BufferCapacity = required;
}
@@ -375,6 +379,7 @@ public static bool IsPrimeCpu(ulong n, CancellationToken ct)
{
Input.Dispose();
Output.Dispose();
HeuristicFlag.Dispose();
DevicePrimesDefault.Dispose();
DevicePrimesLastOne.Dispose();
DevicePrimesLastSeven.Dispose();