diff --git a/EvenPerfectBitScanner/Program.cs b/EvenPerfectBitScanner/Program.cs index 6cc12b4..767bac8 100644 --- a/EvenPerfectBitScanner/Program.cs +++ b/EvenPerfectBitScanner/Program.cs @@ -419,6 +419,7 @@ internal static class Program if (useByDivisor) { + int byDivisorPrimeRange = Math.Max(1, _cliArguments.BlockSize); MersenneNumberDivisorByDivisorTester.Run( byDivisorCandidates, _byDivisorTester!, @@ -427,7 +428,8 @@ internal static class Program static () => _lastCompositeP = true, static () => _lastCompositeP = false, static (candidate, searchedMersenne, detailedCheck, passedAllTests) => CalculationResultHandler.HandleResult(candidate, searchedMersenne, detailedCheck, passedAllTests, _lastCompositeP), - threadCount); + threadCount, + byDivisorPrimeRange); CalculationResultHandler.FlushBuffer(); CalculationResultHandler.ReleaseOutputBuffer(); diff --git a/PerfectNumbers.Core.Tests/MersenneNumberDivisorByDivisorTesterTests.cs b/PerfectNumbers.Core.Tests/MersenneNumberDivisorByDivisorTesterTests.cs index 49778cc..35b2fda 100644 --- a/PerfectNumbers.Core.Tests/MersenneNumberDivisorByDivisorTesterTests.cs +++ b/PerfectNumbers.Core.Tests/MersenneNumberDivisorByDivisorTesterTests.cs @@ -23,7 +23,8 @@ public class MersenneNumberDivisorByDivisorTesterTests markComposite: () => compositeMarks++, clearComposite: () => clearedMarks++, printResult: (prime, searched, detailed, passed) => results.Add((prime, searched, detailed, passed)), - threadCount: 1); + threadCount: 1, + primesPerTask: 2); tester.ConfiguredMaxPrime.Should().Be(13UL); compositeMarks.Should().Be(2); diff --git a/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs b/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs index 008ddd5..dbbb8d9 100644 --- a/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs +++ b/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs @@ -1,4 +1,5 @@ using System.Buffers; +using System.Collections.Concurrent; using System.Globalization; using System.Runtime.InteropServices; @@ -14,7 +15,8 @@ public static class MersenneNumberDivisorByDivisorTester Action markComposite, Action clearComposite, Action printResult, - int threadCount) + int threadCount, + int primesPerTask) { if (candidates.Count == 0) { @@ -233,6 +235,8 @@ public static class MersenneNumberDivisorByDivisorTester // workerCount = 1; // } + int chunkSize = primesPerTask <= 0 ? 1 : primesPerTask; + void ProcessPrime(ulong prime) { bool isPrime = tester.IsPrime(prime, out bool divisorsExhausted); @@ -264,7 +268,20 @@ public static class MersenneNumberDivisorByDivisorTester TaskScheduler = scheduler }; - Parallel.ForEach(filteredPrimes, options, ProcessPrime); + int totalCount = filteredPrimes.Count; + int partitionSize = chunkSize < 1 ? 1 : chunkSize; + if (partitionSize > totalCount) + { + partitionSize = totalCount; + } + + Parallel.ForEach(Partitioner.Create(0, totalCount, partitionSize), options, range => + { + for (int index = range.Item1; index < range.Item2; index++) + { + ProcessPrime(filteredPrimes[index]); + } + }); } } }