From 421cb8ae7d2d6e6260750fb5fcc6b0fc91869dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Lema=C5=84czyk?= Date: Sun, 12 Oct 2025 00:00:47 +0200 Subject: [PATCH] Group by-divisor CPU workloads per worker --- .../MersenneNumberDivisorByDivisorTester.cs | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs b/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs index 82b9e18..e4f85fa 100644 --- a/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs +++ b/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs @@ -257,21 +257,48 @@ public static class MersenneNumberDivisorByDivisorTester printResult(prime, true, divisorsExhausted, true); } - if (workerCount == 1) + if (workerCount > filteredPrimes.Count) + { + workerCount = filteredPrimes.Count; + } + + if (workerCount <= 1) { foreach (ulong prime in filteredPrimes) { ProcessPrime(prime); } - } - else - { - ParallelOptions options = new() - { - MaxDegreeOfParallelism = workerCount - }; - Parallel.ForEach(filteredPrimes, options, ProcessPrime); + return; } + + Task[] workers = new Task[workerCount]; + int totalPrimeCount = filteredPrimes.Count; + int baseGroupSize = totalPrimeCount / workerCount; + int remaining = totalPrimeCount % workerCount; + int groupStartIndex = 0; + + for (int workerIndex = 0; workerIndex < workerCount; workerIndex++) + { + int groupSize = baseGroupSize; + if (workerIndex < remaining) + { + groupSize++; + } + + int startIndex = groupStartIndex; + int endIndex = startIndex + groupSize; + groupStartIndex = endIndex; + + workers[workerIndex] = Task.Run(() => + { + for (int candidateIndex = startIndex; candidateIndex < endIndex; candidateIndex++) + { + ProcessPrime(filteredPrimes[candidateIndex]); + } + }); + } + + Task.WaitAll(workers); } }