Merge pull request #13 from mlemanczyk/codex/check-thread-initialization-in-evenperfectbitscanner
Assign contiguous p ranges to worker threads
This commit is contained in:
1 file changed
+65
-59
@@ -589,46 +589,40 @@ internal static class Program
|
|||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Starting scan...");
|
Console.WriteLine("Starting scan...");
|
||||||
_state = ((long)currentP << 3) | (long)remainder;
|
_state = ((long)currentP << 3) | (long)remainder;
|
||||||
Task[] tasks = new Task[threadCount];
|
Task[] tasks = new Task[threadCount];
|
||||||
|
|
||||||
for (int i = 0; i < threadCount; i++)
|
for (int i = 0; i < threadCount; i++)
|
||||||
{
|
{
|
||||||
tasks[i] = Task.Run(() =>
|
tasks[i] = Task.Run(() =>
|
||||||
{
|
{
|
||||||
ulong[] buffer = new ulong[blockSize];
|
ulong[] buffer = new ulong[blockSize];
|
||||||
while (!Volatile.Read(ref _limitReached))
|
while (!Volatile.Read(ref _limitReached))
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = ReserveBlock(buffer, blockSize);
|
||||||
while (count < blockSize && !Volatile.Read(ref _limitReached))
|
if (count == 0)
|
||||||
{
|
{
|
||||||
buffer[count] = ReserveNextP();
|
break;
|
||||||
count++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0)
|
for (int j = 0; j < count && !Volatile.Read(ref _limitReached); j++)
|
||||||
{
|
{
|
||||||
break;
|
ulong p = buffer[j];
|
||||||
}
|
if (useFilter && !filter.Contains(p))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (useFilter)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Testing {p}");
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < count && !Volatile.Read(ref _limitReached); j++)
|
bool isPerfect = IsEvenPerfectCandidate(p, divisorCyclesSearchLimit, out bool searchedMersenne, out bool detailedCheck);
|
||||||
{
|
PrintResult(p, searchedMersenne, detailedCheck, isPerfect);
|
||||||
ulong p = buffer[j];
|
}
|
||||||
if (useFilter && !filter.Contains(p))
|
}
|
||||||
{
|
});
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
else if (useFilter)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Testing {p}");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isPerfect = IsEvenPerfectCandidate(p, out bool searchedMersenne, out bool detailedCheck);
|
|
||||||
PrintResult(p, searchedMersenne, detailedCheck, isPerfect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Task.WaitAll(tasks);
|
Task.WaitAll(tasks);
|
||||||
FlushBuffer();
|
FlushBuffer();
|
||||||
@@ -742,24 +736,36 @@ internal static class Program
|
|||||||
return $"even_perfect_bit_scan_inc-{inc}_thr-{threads}_blk-{block}_mers-{mers}_mersdev-{mersenneDevice}_ntt-{ntt}_red-{red}_primesdev-{primesDevice}_{order}_orderdev-{orderDevice}_{gcd}_{work}_gputh-{gpuPrimeThreads}_llslice-{llSlice}_scanb-{gpuScanBatch}_warm-{warmupLimit}.csv";
|
return $"even_perfect_bit_scan_inc-{inc}_thr-{threads}_blk-{block}_mers-{mers}_mersdev-{mersenneDevice}_ntt-{ntt}_red-{red}_primesdev-{primesDevice}_{order}_orderdev-{orderDevice}_{gcd}_{work}_gputh-{gpuPrimeThreads}_llslice-{llSlice}_scanb-{gpuScanBatch}_warm-{warmupLimit}.csv";
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static unsafe ulong ReserveNextP()
|
private static unsafe int ReserveBlock(ulong[] buffer, int blockSize)
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
long state = Volatile.Read(ref _state);
|
long state = Volatile.Read(ref _state);
|
||||||
ulong current = (ulong)state >> 3;
|
ulong current = (ulong)state >> 3;
|
||||||
ulong remainder = ((ulong)state) & 7UL;
|
ulong remainder = ((ulong)state) & 7UL;
|
||||||
|
|
||||||
ulong next = _transformP(current, ref remainder);
|
ulong p = current;
|
||||||
long newState = ((long)next << 3) | (long)remainder;
|
int count = 0;
|
||||||
long original = Interlocked.CompareExchange(ref _state, newState, state);
|
while (count < blockSize && !Volatile.Read(ref _limitReached))
|
||||||
if (original == state)
|
{
|
||||||
{
|
buffer[count++] = p;
|
||||||
return current;
|
p = _transformP(p, ref remainder);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
if (count == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long newState = ((long)p << 3) | (long)remainder;
|
||||||
|
long original = Interlocked.CompareExchange(ref _state, newState, state);
|
||||||
|
if (original == state)
|
||||||
|
{
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static void PrintResult(ulong currentP, bool searchedMersenne, bool detailedCheck, bool isPerfect)
|
private static void PrintResult(ulong currentP, bool searchedMersenne, bool detailedCheck, bool isPerfect)
|
||||||
@@ -948,11 +954,11 @@ internal static class Program
|
|||||||
return remainder == 1UL;
|
return remainder == 1UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static bool IsEvenPerfectCandidate(ulong p)
|
internal static bool IsEvenPerfectCandidate(ulong p)
|
||||||
{
|
{
|
||||||
return IsEvenPerfectCandidate(p, out _, out _);
|
return IsEvenPerfectCandidate(p, 0, out _, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool IsEvenPerfectCandidate(ulong p, int divisorCyclesSearchLimit, out bool searchedMersenne, out bool detailedCheck)
|
internal static bool IsEvenPerfectCandidate(ulong p, int divisorCyclesSearchLimit, out bool searchedMersenne, out bool detailedCheck)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user