X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=f4c77847d25bb814956c3b110741e9229603b846;hp=dc5164ea38a99e85faff9f9e499b85c39f71bf18;hb=77fa960f8923ca83ba0391835d50f4230ac6a345;hpb=8c3a5bbc5284897cb944e4bb5748c58813687ba9 diff --git a/src/search.cpp b/src/search.cpp index dc5164ea..f4c77847 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -127,6 +127,35 @@ namespace { Move pv[3]; }; + // Set of rows with half bits set to 1 and half to 0. It is used to allocate + // the search depths across the threads. + typedef std::vector Row; + + const Row HalfDensity[] = { + {0, 1}, + {1, 0}, + {0, 0, 1, 1}, + {0, 1, 1, 0}, + {1, 1, 0, 0}, + {1, 0, 0, 1}, + {0, 0, 0, 1, 1, 1}, + {0, 0, 1, 1, 1, 0}, + {0, 1, 1, 1, 0, 0}, + {1, 1, 1, 0, 0, 0}, + {1, 1, 0, 0, 0, 1}, + {1, 0, 0, 0, 1, 1}, + {0, 0, 0, 0, 1, 1, 1, 1}, + {0, 0, 0, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 0 ,0}, + {0, 1, 1, 1, 1, 0, 0 ,0}, + {1, 1, 1, 1, 0, 0, 0 ,0}, + {1, 1, 1, 0, 0, 0, 0 ,1}, + {1, 1, 0, 0, 0, 0, 1 ,1}, + {1, 0, 0, 0, 0, 1, 1 ,1}, + }; + + const size_t HalfDensitySize = std::extent::value; + EasyMoveManager EasyMove; Value DrawValue[COLOR_NB]; CounterMoveHistoryStats CounterMoveHistory; @@ -394,27 +423,12 @@ void Thread::search() { while (++rootDepth < DEPTH_MAX && !Signals.stop && (!Limits.depth || rootDepth <= Limits.depth)) { // Set up the new depths for the helper threads skipping on average every - // 2nd ply (using a half-density map similar to a Hadamard matrix). + // 2nd ply (using a half-density matrix). if (!mainThread) { - int d = rootDepth + rootPos.game_ply(); - - if (idx <= 6 || idx > 24) - { - if (((d + idx) >> (msb(idx + 1) - 1)) % 2) - continue; - } - else - { - // Table of values of 6 bits with 3 of them set - static const int HalfDensityMap[] = { - 0x07, 0x0b, 0x0d, 0x0e, 0x13, 0x16, 0x19, 0x1a, 0x1c, - 0x23, 0x25, 0x26, 0x29, 0x2c, 0x31, 0x32, 0x34, 0x38 - }; - - if ((HalfDensityMap[idx - 7] >> (d % 6)) & 1) - continue; - } + const Row& row = HalfDensity[(idx - 1) % HalfDensitySize]; + if (row[(rootDepth + rootPos.game_ply()) % row.size()]) + continue; } // Age out PV variability metric @@ -532,10 +546,6 @@ void Thread::search() { { if (!Signals.stop && !Signals.stopOnPonderhit) { - // Take some extra time if the best move has changed - if (rootDepth > 4 * ONE_PLY && multiPV == 1) - Time.pv_instability(mainThread->bestMoveChanges); - // Stop the search if only one legal move is available, or if all // of the available time has been used, or if we matched an easyMove // from the previous search and just did a fast verification. @@ -543,13 +553,14 @@ void Thread::search() { bestValue >= mainThread->previousScore }; int improvingFactor = 640 - 160*F[0] - 126*F[1] - 124*F[0]*F[1]; + double unstablePvFactor = 1 + mainThread->bestMoveChanges; bool doEasyMove = rootMoves[0].pv[0] == easyMove && mainThread->bestMoveChanges < 0.03 - && Time.elapsed() > Time.available() * 25 / 206; + && Time.elapsed() > Time.optimum() * 25 / 204; if ( rootMoves.size() == 1 - || Time.elapsed() > Time.available() * improvingFactor / 640 + || Time.elapsed() > Time.optimum() * unstablePvFactor * improvingFactor / 634 || (mainThread->easyMovePlayed = doEasyMove)) { // If we are allowed to ponder do not stop the search now but @@ -958,7 +969,7 @@ moves_loop: // When in check search starts from here && cmh[pos.moved_piece(move)][to_sq(move)] < VALUE_ZERO) continue; - predictedDepth = newDepth - reduction(improving, depth, moveCount); + predictedDepth = std::max(newDepth - reduction(improving, depth, moveCount), DEPTH_ZERO); // Futility pruning: parent node if (predictedDepth < 7 * ONE_PLY)