X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=2fa2ce7e27cb4e41c0243a8f55f987b3d8f2dd35;hp=9c3e17b6606bf257f3fa0b6de275bcfd3497599a;hb=a47bbca0ea40ac007d64682c3ba51fa4158b2d3f;hpb=c0bb0415394179e9c771cc96a9da6724fc14c167 diff --git a/src/search.cpp b/src/search.cpp index 9c3e17b6..2fa2ce7e 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -113,8 +113,8 @@ namespace { std::copy(newPv.begin(), newPv.begin() + 3, pv); StateInfo st[2]; - pos.do_move(newPv[0], st[0], pos.gives_check(newPv[0])); - pos.do_move(newPv[1], st[1], pos.gives_check(newPv[1])); + pos.do_move(newPv[0], st[0]); + pos.do_move(newPv[1], st[1]); expectedPosKey = pos.key(); pos.undo_move(newPv[1]); pos.undo_move(newPv[0]); @@ -153,6 +153,9 @@ namespace { {1, 0, 0, 0, 0, 1, 1 ,1}, }; + Value bonus(Depth depth) { int d = depth / ONE_PLY ; return Value(d * d + 2 * d - 2); } + Value penalty(Depth depth) { int d = depth / ONE_PLY ; return -Value(d * d + 4 * d + 1); } + const size_t HalfDensitySize = std::extent::value; EasyMoveManager EasyMove; @@ -183,8 +186,6 @@ void Search::init() { for (int mc = 1; mc < 64; ++mc) { double r = log(d) * log(mc) / 2; - if (r < 0.80) - continue; Reductions[NonPV][imp][d][mc] = int(std::round(r)); Reductions[PV][imp][d][mc] = std::max(Reductions[NonPV][imp][d][mc] - 1, 0); @@ -214,6 +215,7 @@ void Search::clear() { th->counterMoves.clear(); th->fromTo.clear(); th->counterMoveHistory.clear(); + th->resetCalls = true; } Threads.main()->previousScore = VALUE_INFINITE; @@ -235,7 +237,7 @@ uint64_t Search::perft(Position& pos, Depth depth) { cnt = 1, nodes++; else { - pos.do_move(m, st, pos.gives_check(m)); + pos.do_move(m, st); cnt = leaf ? MoveList(pos).size() : perft(pos, depth - ONE_PLY); nodes += cnt; pos.undo_move(m); @@ -336,12 +338,12 @@ void MainThread::search() { void Thread::search() { - Stack stack[MAX_PLY+7], *ss = stack+5; // To allow referencing (ss-5) and (ss+2) + Stack stack[MAX_PLY+7], *ss = stack+4; // To allow referencing (ss-4) and (ss+2) Value bestValue, alpha, beta, delta; Move easyMove = MOVE_NONE; MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr); - std::memset(ss-5, 0, 8 * sizeof(Stack)); + std::memset(ss-4, 0, 7 * sizeof(Stack)); bestValue = delta = alpha = -VALUE_INFINITE; beta = VALUE_INFINITE; @@ -574,9 +576,13 @@ namespace { if (thisThread->resetCalls.load(std::memory_order_relaxed)) { thisThread->resetCalls = false; - thisThread->callsCnt = 0; + // At low node count increase the checking rate to about 0.1% of nodes + // otherwise use a default value. + thisThread->callsCnt = Limits.nodes ? std::min((int64_t)4096, Limits.nodes / 1024) + : 4096; } - if (++thisThread->callsCnt > 4096) + + if (--thisThread->callsCnt <= 0) { for (Thread* th : Threads) th->resetCalls = true; @@ -613,6 +619,7 @@ namespace { ss->counterMoves = nullptr; (ss+1)->skipEarlyPruning = false; (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE; + Square prevSq = to_sq((ss-1)->currentMove); // Step 4. Transposition table lookup. We don't want the score of a partial // search to overwrite a previous full search TT value, so we use a different @@ -635,21 +642,12 @@ namespace { // If ttMove is quiet, update killers, history, counter move on TT hit if (ttValue >= beta && ttMove) { - int d = depth / ONE_PLY; - if (!pos.capture_or_promotion(ttMove)) - { - Value bonus = Value(d * d + 2 * d - 2); - update_stats(pos, ss, ttMove, nullptr, 0, bonus); - } + update_stats(pos, ss, ttMove, nullptr, 0, bonus(depth)); // Extra penalty for a quiet TT move in previous ply when it gets refuted if ((ss-1)->moveCount == 1 && !pos.captured_piece()) - { - Value penalty = Value(d * d + 4 * d + 1); - Square prevSq = to_sq((ss-1)->currentMove); - update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, -penalty); - } + update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, penalty(depth)); } return ttValue; } @@ -802,7 +800,7 @@ namespace { { ss->currentMove = move; ss->counterMoves = &thisThread->counterMoveHistory[pos.moved_piece(move)][to_sq(move)]; - pos.do_move(move, st, pos.gives_check(move)); + pos.do_move(move, st); value = -search(pos, ss+1, -rbeta, -rbeta+1, rdepth, !cutNode); pos.undo_move(move); if (value >= rbeta) @@ -945,10 +943,16 @@ moves_loop: // When in check search starts from here && !pos.see_ge(move, Value(-35 * lmrDepth * lmrDepth))) continue; } - else if ( depth < 7 * ONE_PLY - && !extension - && !pos.see_ge(move, Value(-35 * depth / ONE_PLY * depth / ONE_PLY))) + else if (depth < 7 * ONE_PLY && !extension) + { + Value v = -Value(399 + 35 * depth / ONE_PLY * depth / ONE_PLY); + + if (PvNode) + v += beta - alpha - 1; + + if (!pos.see_ge(move, v)) continue; + } } // Speculative prefetch as early as possible @@ -985,10 +989,8 @@ moves_loop: // When in check search starts from here // Decrease reduction for moves that escape a capture. Filter out // castling moves, because they are coded as "king captures rook" and - // hence break make_move(). Also use see() instead of see_sign(), - // because the destination square is empty. + // hence break make_move(). else if ( type_of(move) == NORMAL - && type_of(pos.piece_on(to_sq(move))) != PAWN && !pos.see_ge(make_move(to_sq(move), from_sq(move)), VALUE_ZERO)) r -= 2 * ONE_PLY; @@ -1133,33 +1135,20 @@ moves_loop: // When in check search starts from here : inCheck ? mated_in(ss->ply) : DrawValue[pos.side_to_move()]; else if (bestMove) { - int d = depth / ONE_PLY; // Quiet best move: update killers, history and countermoves if (!pos.capture_or_promotion(bestMove)) - { - Value bonus = Value(d * d + 2 * d - 2); - update_stats(pos, ss, bestMove, quietsSearched, quietCount, bonus); - } + update_stats(pos, ss, bestMove, quietsSearched, quietCount, bonus(depth)); // Extra penalty for a quiet TT move in previous ply when it gets refuted if ((ss-1)->moveCount == 1 && !pos.captured_piece()) - { - Value penalty = Value(d * d + 4 * d + 1); - Square prevSq = to_sq((ss-1)->currentMove); - update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, -penalty); - } + update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, penalty(depth)); } // Bonus for prior countermove that caused the fail low else if ( depth >= 3 * ONE_PLY && !pos.captured_piece() && is_ok((ss-1)->currentMove)) - { - int d = depth / ONE_PLY; - Value bonus = Value(d * d + 2 * d - 2); - Square prevSq = to_sq((ss-1)->currentMove); - update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, bonus); - } + update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, bonus(depth)); tte->save(posKey, value_to_tt(bestValue, ss->ply), bestValue >= beta ? BOUND_LOWER : @@ -1602,7 +1591,7 @@ bool RootMove::extract_ponder_from_tt(Position& pos) { if (!pv[0]) return false; - pos.do_move(pv[0], st, pos.gives_check(pv[0])); + pos.do_move(pv[0], st); TTEntry* tte = TT.probe(pos.key(), ttHit); if (ttHit)