X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=933b403070c7b42689544fc962a19525e236bfb3;hp=cc910f7d81da39c5f1d1b42ebbd36567cd6abd79;hb=06e0d48794d9872ef627e15d5edf3bbcb7ad1752;hpb=ffa150bec3af540fbaff57fdbb657940225e69e6 diff --git a/src/search.cpp b/src/search.cpp index cc910f7d..933b4030 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -560,7 +560,8 @@ namespace { // Start with a small aspiration window and, in case of fail high/low, // research with bigger window until not failing high/low anymore. do { - // Search starting from ss+1 to allow calling update_gains() + // Search starting from ss+1 to allow referencing (ss-1). This is + // needed by update_gains() and ss copy when splitting at Root. value = search(pos, ss+1, alpha, beta, depth * ONE_PLY); // It is critical that sorting is done with a stable algorithm @@ -711,7 +712,7 @@ namespace { Depth ext, newDepth; ValueType vt; Value bestValue, value, oldAlpha; - Value refinedValue, nullValue, futilityBase, futilityValueScaled; // Non-PV specific + Value refinedValue, nullValue, futilityBase, futilityValue; bool isPvMove, inCheck, singularExtensionNode, givesCheck, captureOrPromotion, dangerous; int moveCount = 0, playedMoveCount = 0; Thread& thread = Threads[pos.thread()]; @@ -1069,19 +1070,19 @@ split_point_start: // At split points actual search starts from here // We illogically ignore reduction condition depth >= 3*ONE_PLY for predicted depth, // but fixing this made program slightly weaker. Depth predictedDepth = newDepth - reduction(depth, moveCount); - futilityValueScaled = futilityBase + futility_margin(predictedDepth, moveCount) - + H.gain(pos.piece_on(move_from(move)), move_to(move)); + futilityValue = futilityBase + futility_margin(predictedDepth, moveCount) + + H.gain(pos.piece_on(move_from(move)), move_to(move)); - if (futilityValueScaled < beta) + if (futilityValue < beta) { if (SpNode) { lock_grab(&(sp->lock)); - if (futilityValueScaled > sp->bestValue) - sp->bestValue = bestValue = futilityValueScaled; + if (futilityValue > sp->bestValue) + sp->bestValue = bestValue = futilityValue; } - else if (futilityValueScaled > bestValue) - bestValue = futilityValueScaled; + else if (futilityValue > bestValue) + bestValue = futilityValue; continue; } @@ -1170,17 +1171,12 @@ split_point_start: // At split points actual search starts from here alpha = sp->alpha; } - - if (RootNode) + // Finished searching the move. If StopRequest is true, the search + // was aborted because the user interrupted the search or because we + // ran out of time. In this case, the return value of the search cannot + // be trusted, and we don't update the best move and/or PV. + if (RootNode && !StopRequest) { - // Finished searching the move. If StopRequest is true, the search - // was aborted because the user interrupted the search or because we - // ran out of time. In this case, the return value of the search cannot - // be trusted, and we break out of the loop without updating the best - // move and/or PV. - if (StopRequest) - break; - // Remember searched nodes counts for this move RootMove* rm = Rml.find(move); rm->nodes += pos.nodes_searched() - nodes; @@ -1232,8 +1228,8 @@ split_point_start: // At split points actual search starts from here && Threads.available_slave_exists(pos.thread()) && !StopRequest && !thread.cutoff_occurred()) - Threads.split(pos, ss, &alpha, beta, &bestValue, depth, - threatMove, moveCount, &mp, NT); + bestValue = Threads.split(pos, ss, alpha, beta, bestValue, depth, + threatMove, moveCount, &mp, NT); } // Step 20. Check for mate and stalemate @@ -1302,6 +1298,7 @@ split_point_start: // At split points actual search starts from here bool inCheck, enoughMaterial, givesCheck, evasionPrunable; const TTEntry* tte; Depth ttDepth; + ValueType vt; Value oldAlpha = alpha; ss->bestMove = ss->currentMove = MOVE_NONE; @@ -1372,7 +1369,7 @@ split_point_start: // At split points actual search starts from here CheckInfo ci(pos); // Loop through the moves until no moves remain or a beta cutoff occurs - while ( alpha < beta + while ( bestValue < beta && (move = mp.get_next_move()) != MOVE_NONE) { assert(move_is_ok(move)); @@ -1392,10 +1389,11 @@ split_point_start: // At split points actual search starts from here + piece_value_endgame(pos.piece_on(move_to(move))) + (move_is_ep(move) ? PawnValueEndgame : VALUE_ZERO); - if (futilityValue < alpha) + if (futilityValue < beta) { if (futilityValue > bestValue) bestValue = futilityValue; + continue; } @@ -1454,11 +1452,12 @@ split_point_start: // At split points actual search starts from here if (value > bestValue) { bestValue = value; - if (value > alpha) - { + ss->bestMove = move; + + if ( PvNode + && value > alpha + && value < beta) // We want always alpha < beta alpha = value; - ss->bestMove = move; - } } } @@ -1468,8 +1467,11 @@ split_point_start: // At split points actual search starts from here return value_mated_in(ss->ply); // Update transposition table - ValueType vt = (bestValue <= oldAlpha ? VALUE_TYPE_UPPER : bestValue >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT); - TT.store(pos.get_key(), value_to_tt(bestValue, ss->ply), vt, ttDepth, ss->bestMove, ss->eval, evalMargin); + move = bestValue <= oldAlpha ? MOVE_NONE : ss->bestMove; + vt = bestValue <= oldAlpha ? VALUE_TYPE_UPPER + : bestValue >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT; + + TT.store(pos.get_key(), value_to_tt(bestValue, ss->ply), vt, ttDepth, move, ss->eval, evalMargin); assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE); @@ -2215,6 +2217,8 @@ void ThreadsManager::idle_loop(int threadID, SplitPoint* sp) { search(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth); else if (tsp->nodeType == NonPV) search(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth); + else + assert(false); assert(threads[threadID].state == Thread::SEARCHING); @@ -2243,8 +2247,6 @@ void ThreadsManager::idle_loop(int threadID, SplitPoint* sp) { // In helpful master concept a master can help only a sub-tree, and // because here is all finished is not possible master is booked. assert(threads[threadID].state == Thread::AVAILABLE); - - threads[threadID].state = Thread::SEARCHING; return; } }