@@ -812,8 +812,10 @@ struct Factorizer {
812812 return 1U ;
813813 }
814814
815- BigInteger monteCarlo (rngType& gen) {
815+ BigInteger monteCarlo (const size_t & CpuCount, const size_t & cpu, rngType& gen) {
816816 // This function enters only once per thread.
817+ const BigInteger threadRange = (batchRange + CpuCount - 1 ) / CpuCount;
818+ const BigInteger threadOffset = batchOffset + threadRange * cpu;
817819 size_t batchPower = 0U ;
818820
819821 // This is the outer reseeding loop.
@@ -822,7 +824,10 @@ struct Factorizer {
822824 BigInteger perfectSquare = 1U ;
823825 std::vector<size_t > fv (primes.size (), 0 );
824826 while (perfectSquare < toFactor) {
825- BigInteger n = forwardFn (((batchOffset + (dis (gen) % batchRange)) * wheelEntryCount) + (dis (gen) % wheelEntryCount));
827+ const BigInteger bIndex = threadOffset + (dis (gen) % threadRange);
828+ const BigInteger halfBIndex = batchOffset + (bIndex >> 1U ) + 1U ;
829+ const BigInteger bNum = (bIndex & 1U ) ? batchTotal - halfBIndex : halfBIndex;
830+ BigInteger n = forwardFn ((bNum * wheelEntryCount) + (dis (gen) % wheelEntryCount));
826831 const std::vector<size_t > pfv = factorizationVector (&n);
827832 if (!pfv.size ()) {
828833 continue ;
@@ -1136,9 +1141,9 @@ std::string find_a_factor(std::string toFactorStr, size_t method, size_t nodeCou
11361141 gen.emplace_back (rng ());
11371142 }
11381143 for (unsigned cpu = 0U ; cpu < CpuCount; ++cpu) {
1139- futures.push_back (std::async (std::launch::async, [&worker, cpu, &gen] {
1144+ futures.push_back (std::async (std::launch::async, [&worker, &CpuCount, cpu, &gen] {
11401145 // This is as "embarrissingly parallel" as it gets.
1141- return worker.monteCarlo (gen[cpu]);
1146+ return worker.monteCarlo (CpuCount, cpu, gen[cpu]);
11421147 }));
11431148 }
11441149 } else {
0 commit comments