@@ -943,76 +943,71 @@ struct Factorizer {
943943 auto ikit = smoothNumberKeys.begin ();
944944 auto ivit = smoothNumberValues.begin ();
945945 BigInteger result = 1U ;
946- batchMutex.lock ();
947- for (size_t i = 0U ; isIncomplete && (i < smoothNumberKeys.size ()); ++i) {
948- dispatch.dispatch ([this , i, ikit, ivit, &result]() -> bool {
949- auto jkit = ikit;
950- auto jvit = ivit;
951-
952- for (size_t j = i; isIncomplete && (j < this ->smoothNumberKeys .size ()); ++j) {
953- if ((*ivit) == (*jvit)) {
954- // The rows have the same value. Hence, multiplied together,
955- // they form a perfect square residue we can check for congruence.
956-
957- // Compute x and y
958- const BigInteger x = ((*ikit) * (*jkit)) % this ->toFactor ;
959- const BigInteger y = modExp (x, this ->toFactor >> 1U , this ->toFactor );
960-
961- // Check congruence of squares
962- BigInteger factor = gcd (this ->toFactor , x + y);
963- if ((factor != 1U ) && (factor != this ->toFactor )) {
964- std::lock_guard<std::mutex> lock (this ->batchMutex );
965- isIncomplete = false ;
966- result = factor;
967-
968- return true ;
969- }
946+ for (size_t i = 0U ; i < smoothNumberKeys.size (); ++i) {
947+ // For lock_guard scope
948+ if (true ) {
949+ std::lock_guard<std::mutex> lock (batchMutex);
950+ dispatch.dispatch ([this , i, ikit, ivit, &result]() -> bool {
951+ auto jkit = ikit;
952+ auto jvit = ivit;
953+
954+ for (size_t j = i; isIncomplete && (j < this ->smoothNumberKeys .size ()); ++j) {
955+ if ((*ivit) == (*jvit)) {
956+ // The rows have the same value. Hence, multiplied together,
957+ // they form a perfect square residue we can check for congruence.
970958
971- if (x != y) {
972- // Try x - y as well
973- factor = gcd (this ->toFactor , x - y);
959+ // Compute x and y
960+ const BigInteger x = ((*ikit) * (*jkit)) % this ->toFactor ;
961+ const BigInteger y = modExp (x, this ->toFactor >> 1U , this ->toFactor );
962+
963+ // Check congruence of squares
964+ BigInteger factor = gcd (this ->toFactor , x + y);
974965 if ((factor != 1U ) && (factor != this ->toFactor )) {
975966 std::lock_guard<std::mutex> lock (this ->batchMutex );
976967 isIncomplete = false ;
977968 result = factor;
978969
979970 return true ;
980971 }
972+
973+ if (x != y) {
974+ // Try x - y as well
975+ factor = gcd (this ->toFactor , x - y);
976+ if ((factor != 1U ) && (factor != this ->toFactor )) {
977+ std::lock_guard<std::mutex> lock (this ->batchMutex );
978+ isIncomplete = false ;
979+ result = factor;
980+
981+ return true ;
982+ }
983+ }
981984 }
985+
986+ // Next inner-loop row (synchronously).
987+ ++jkit;
988+ ++jvit;
982989 }
983990
984- // Next inner-loop row (synchronously).
985- ++jkit;
986- ++jvit;
991+ return false ;
992+ });
993+ // Still in lock_guard scope:
994+ if (!isIncomplete) {
995+ break ;
987996 }
988-
989- return false ;
990- });
991-
997+ }
992998 // If we are still dispatching items in the queue,
993999 // they probably won't have completed, but let
9941000 // them take a turn with the mutex.
995- batchMutex.unlock ();
9961001
9971002 // Next outer-loop row (all dispatched at once).
9981003 ++ikit;
9991004 ++ivit;
1000-
1001- // If this actually contends, we'll exit now.
1002- batchMutex.lock ();
10031005 }
10041006
1005- if (result == 1U ) {
1006- // The result has not yet been found.
1007- // A succesful item will dump the queue.
1008- batchMutex.unlock ();
1009- dispatch.finish ();
1010- } else {
1011- // The result has been found.
1012- // If any work remains, dump it.
1013- batchMutex.unlock ();
1014- dispatch.dump ();
1015- }
1007+ // The result has not yet been found.
1008+ // A succesful item will dump the queue.
1009+ // If it's already dumped, this does nothing.
1010+ dispatch.finish ();
10161011
10171012 // Depending on row count, a successful result should be nearly guaranteed.
10181013 return result;
0 commit comments