From c1dc2e14d5a133f5eed356ab5952f5178f7dab58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Lema=C5=84czyk?= Date: Thu, 11 Sep 2025 02:36:16 +0200 Subject: [PATCH] Allocate unique p ranges per thread --- EvenPerfectBitScanner/Program.cs | 124 ++++++++++++++++--------------- 1 file changed, 65 insertions(+), 59 deletions(-) diff --git a/EvenPerfectBitScanner/Program.cs b/EvenPerfectBitScanner/Program.cs index 4d482d1..526c71b 100644 --- a/EvenPerfectBitScanner/Program.cs +++ b/EvenPerfectBitScanner/Program.cs @@ -589,46 +589,40 @@ internal static class Program } Console.WriteLine("Starting scan..."); - _state = ((long)currentP << 3) | (long)remainder; - Task[] tasks = new Task[threadCount]; + _state = ((long)currentP << 3) | (long)remainder; + Task[] tasks = new Task[threadCount]; - for (int i = 0; i < threadCount; i++) - { - tasks[i] = Task.Run(() => - { - ulong[] buffer = new ulong[blockSize]; - while (!Volatile.Read(ref _limitReached)) - { - int count = 0; - while (count < blockSize && !Volatile.Read(ref _limitReached)) - { - buffer[count] = ReserveNextP(); - count++; - } + for (int i = 0; i < threadCount; i++) + { + tasks[i] = Task.Run(() => + { + ulong[] buffer = new ulong[blockSize]; + while (!Volatile.Read(ref _limitReached)) + { + int count = ReserveBlock(buffer, blockSize); + if (count == 0) + { + break; + } - if (count == 0) - { - break; - } + for (int j = 0; j < count && !Volatile.Read(ref _limitReached); j++) + { + 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++) - { - 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); - } - } - }); - } + bool isPerfect = IsEvenPerfectCandidate(p, divisorCyclesSearchLimit, out bool searchedMersenne, out bool detailedCheck); + PrintResult(p, searchedMersenne, detailedCheck, isPerfect); + } + } + }); + } Task.WaitAll(tasks); 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"; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe ulong ReserveNextP() - { - while (true) - { - long state = Volatile.Read(ref _state); - ulong current = (ulong)state >> 3; - ulong remainder = ((ulong)state) & 7UL; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe int ReserveBlock(ulong[] buffer, int blockSize) + { + while (true) + { + long state = Volatile.Read(ref _state); + ulong current = (ulong)state >> 3; + ulong remainder = ((ulong)state) & 7UL; - ulong next = _transformP(current, ref remainder); - long newState = ((long)next << 3) | (long)remainder; - long original = Interlocked.CompareExchange(ref _state, newState, state); - if (original == state) - { - return current; - } - } - } + ulong p = current; + int count = 0; + while (count < blockSize && !Volatile.Read(ref _limitReached)) + { + buffer[count++] = p; + 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)] private static void PrintResult(ulong currentP, bool searchedMersenne, bool detailedCheck, bool isPerfect) @@ -948,11 +954,11 @@ internal static class Program return remainder == 1UL; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool IsEvenPerfectCandidate(ulong p) - { - return IsEvenPerfectCandidate(p, out _, out _); - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsEvenPerfectCandidate(ulong p) + { + return IsEvenPerfectCandidate(p, 0, out _, out _); + } internal static bool IsEvenPerfectCandidate(ulong p, int divisorCyclesSearchLimit, out bool searchedMersenne, out bool detailedCheck) {