Optimizations
This commit is contained in:
1 parent
7079d108e7
commit
773848c577
1 file changed
+46
-28
@@ -318,27 +318,45 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
|
|||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int consoleStatus = 0;
|
int consoleStatus = 0;
|
||||||
bool useCycles = _owner._useDivisorCycles;
|
MersenneNumberDivisorByDivisorGpuTester owner = _owner;
|
||||||
|
int gpuBatchSize = owner._gpuBatchSize;
|
||||||
|
bool useCycles = owner._useDivisorCycles;
|
||||||
|
byte[] hitsHost = _hitsHost;
|
||||||
|
int[] indexHost = _indexHost;
|
||||||
|
ulong[] primesHost = _primesHost;
|
||||||
|
Accelerator accelerator = _accelerator;
|
||||||
|
MemoryBuffer1D<byte, Stride1D.Dense> hitsBuffer = _hitsBuffer;
|
||||||
|
MemoryBuffer1D<ulong, Stride1D.Dense> primesBuffer = _primesBuffer;
|
||||||
|
ArrayView1D<ulong, Stride1D.Dense> primesBufferView = primesBuffer.View;
|
||||||
|
ArrayView1D<byte, Stride1D.Dense> hitsBufferView = hitsBuffer.View;
|
||||||
|
Action<Index1D, MontgomeryDivisorData, ArrayView<ulong>, ArrayView<byte>> kernel = _kernel;
|
||||||
|
ArrayView1D<ulong, Stride1D.Dense> primesView;
|
||||||
|
ArrayView1D<byte, Stride1D.Dense> hitsView;
|
||||||
MersenneDivisorCycles? divisorCycles = useCycles ? MersenneDivisorCycles.Shared : null;
|
MersenneDivisorCycles? divisorCycles = useCycles ? MersenneDivisorCycles.Shared : null;
|
||||||
ulong cycle = useCycles ? divisorCycles!.GetCycle(divisor) : 0UL;
|
ulong cycle = useCycles ? divisorCycles!.GetCycle(divisor) : 0UL, primeValue;
|
||||||
MontgomeryDivisorData divisorData = CreateMontgomeryDivisorData(divisor);
|
MontgomeryDivisorData divisorData = CreateMontgomeryDivisorData(divisor);
|
||||||
Span<ulong> primeSpan = _primesHost.AsSpan(0, _owner._gpuBatchSize);
|
Span<ulong> primeSpan = primesHost.AsSpan(0, gpuBatchSize);
|
||||||
Span<int> indexSpan = _indexHost.AsSpan(0, _owner._gpuBatchSize);
|
ref ulong primesSpanRef = ref MemoryMarshal.GetReference(primeSpan);
|
||||||
Span<byte> hitSpan = _hitsHost.AsSpan(0, _owner._gpuBatchSize);
|
Span<int> indexSpan = indexHost.AsSpan(0, gpuBatchSize);
|
||||||
int currentSpanSize = _owner._gpuBatchSize;
|
Span<byte> hitsSlice, hitSpan = hitsHost.AsSpan(0, gpuBatchSize);
|
||||||
|
ref byte hitSpanRef = ref MemoryMarshal.GetReference(hitSpan);
|
||||||
|
int batchSize, currentSpanSize = gpuBatchSize, gpuCount, i, primesLength = primes.Length;
|
||||||
|
|
||||||
while (offset < primes.Length)
|
while (offset < primesLength)
|
||||||
{
|
{
|
||||||
int batchSize = Math.Min(_owner._gpuBatchSize, primes.Length - offset);
|
batchSize = Math.Min(gpuBatchSize, primesLength - offset);
|
||||||
if (batchSize != currentSpanSize)
|
if (batchSize != currentSpanSize)
|
||||||
{
|
{
|
||||||
primeSpan = _primesHost.AsSpan(0, batchSize);
|
primeSpan = primesHost.AsSpan(0, batchSize);
|
||||||
indexSpan = _indexHost.AsSpan(0, batchSize);
|
primesSpanRef = ref MemoryMarshal.GetReference(primeSpan);
|
||||||
hitSpan = _hitsHost.AsSpan(0, batchSize);
|
indexSpan = indexHost.AsSpan(0, batchSize);
|
||||||
|
hitSpan = hitsHost.AsSpan(0, batchSize);
|
||||||
|
hitSpanRef = ref MemoryMarshal.GetReference(hitSpan);
|
||||||
currentSpanSize = batchSize;
|
currentSpanSize = batchSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
primes.Slice(offset, batchSize).CopyTo(primeSpan);
|
// We benefit from the constructor, because CopyTo will be called as static function
|
||||||
|
new Span<ulong>(primesHost, offset, batchSize).CopyTo(primeSpan);
|
||||||
|
|
||||||
if (++consoleStatus == PerfectNumberConstants.ConsoleInterval)
|
if (++consoleStatus == PerfectNumberConstants.ConsoleInterval)
|
||||||
{
|
{
|
||||||
@@ -346,14 +364,14 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
|
|||||||
consoleStatus = 0;
|
consoleStatus = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Span<byte> hitsSlice = hits.Slice(offset, batchSize);
|
hitsSlice = hits.Slice(offset, batchSize);
|
||||||
int gpuCount = 0;
|
gpuCount = 0;
|
||||||
|
|
||||||
if (useCycles)
|
if (useCycles)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < batchSize; i++)
|
for (i = 0; i < batchSize; i++)
|
||||||
{
|
{
|
||||||
ulong primeValue = primeSpan[i];
|
primeValue = primeSpan[i];
|
||||||
if (cycle == 0UL || primeValue % cycle != 0UL)
|
if (cycle == 0UL || primeValue % cycle != 0UL)
|
||||||
{
|
{
|
||||||
hitsSlice[i] = 0;
|
hitsSlice[i] = 0;
|
||||||
@@ -367,15 +385,15 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
|
|||||||
|
|
||||||
if (gpuCount > 0)
|
if (gpuCount > 0)
|
||||||
{
|
{
|
||||||
var primesView = _primesBuffer.View.SubView(0, gpuCount);
|
primesView = primesBufferView.SubView(0, gpuCount);
|
||||||
var hitsView = _hitsBuffer.View.SubView(0, gpuCount);
|
hitsView = hitsBufferView.SubView(0, gpuCount);
|
||||||
|
|
||||||
primesView.CopyFromCPU(ref MemoryMarshal.GetReference(primeSpan), gpuCount);
|
primesView.CopyFromCPU(ref primesSpanRef, gpuCount);
|
||||||
_kernel(gpuCount, divisorData, primesView, hitsView);
|
kernel(gpuCount, divisorData, primesView, hitsView);
|
||||||
_accelerator.Synchronize();
|
accelerator.Synchronize();
|
||||||
|
|
||||||
hitsView.CopyToCPU(ref MemoryMarshal.GetReference(hitSpan), gpuCount);
|
hitsView.CopyToCPU(ref hitSpanRef, gpuCount);
|
||||||
for (int i = 0; i < gpuCount; i++)
|
for (i = 0; i < gpuCount; i++)
|
||||||
{
|
{
|
||||||
hitsSlice[indexSpan[i]] = hitSpan[i];
|
hitsSlice[indexSpan[i]] = hitSpan[i];
|
||||||
}
|
}
|
||||||
@@ -383,12 +401,12 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var primesView = _primesBuffer.View.SubView(0, batchSize);
|
primesView = primesBufferView.SubView(0, batchSize);
|
||||||
var hitsView = _hitsBuffer.View.SubView(0, batchSize);
|
hitsView = hitsBufferView.SubView(0, batchSize);
|
||||||
|
|
||||||
primesView.CopyFromCPU(ref MemoryMarshal.GetReference(primeSpan), batchSize);
|
primesView.CopyFromCPU(ref primesSpanRef, batchSize);
|
||||||
_kernel(batchSize, divisorData, primesView, hitsView);
|
kernel(batchSize, divisorData, primesView, hitsView);
|
||||||
_accelerator.Synchronize();
|
accelerator.Synchronize();
|
||||||
|
|
||||||
hitsView.CopyToCPU(ref MemoryMarshal.GetReference(hitSpan), batchSize);
|
hitsView.CopyToCPU(ref MemoryMarshal.GetReference(hitSpan), batchSize);
|
||||||
hitSpan.CopyTo(hitsSlice);
|
hitSpan.CopyTo(hitsSlice);
|
||||||
|
|||||||
Reference in new issue
Block a user