X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fsearch.cpp;h=6d05405b6f79c9ad002824bbafd0777b132f000b;hb=706b44a966a6ea2fe9a1a7adaf28f7964eec3115;hp=c1cbc9ef1d4d7c3328ccffaf183d6f8b1d405e55;hpb=4ead60e2a77892dbeedb36f4557da5eba2f0558b;p=stockfish diff --git a/src/search.cpp b/src/search.cpp index c1cbc9ef..6d05405b 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -611,7 +611,7 @@ namespace { // Initialize FIXME move before Rml.init() TT.new_search(); H.clear(); - memset(ss, 0, PLY_MAX_PLUS_2 * sizeof(SearchStack)); + memset(ss, 0, 4 * sizeof(SearchStack)); *ponderMove = bestMove = easyMove = MOVE_NONE; depth = aspirationDelta = 0; ss->currentMove = MOVE_NULL; // Hack to skip update_gains() @@ -801,7 +801,8 @@ namespace { bestValue = alpha; // Step 1. Initialize node and poll. Polling can abort search - ss->currentMove = ss->bestMove = threatMove = MOVE_NONE; + ss->currentMove = ss->bestMove = threatMove = (ss+1)->excludedMove = MOVE_NONE; + (ss+1)->skipNullMove = false; (ss+1)->reduction = DEPTH_ZERO; (ss+2)->killers[0] = (ss+2)->killers[1] = (ss+2)->mateKiller = MOVE_NONE; if (threadID == 0 && ++NodesSincePoll > NodesBetweenPolls) @@ -1070,7 +1071,7 @@ split_point_start: // At split points actual search starts from here // Update current move (this must be done after singular extension search) ss->currentMove = move; - newDepth = depth - (!Root ? ONE_PLY : DEPTH_ZERO) + ext; + newDepth = depth - ONE_PLY + ext; // Step 12. Futility pruning (is omitted in PV nodes) if ( !PvNode @@ -1153,8 +1154,7 @@ split_point_start: // At split points actual search starts from here && ss->killers[0] != move && ss->killers[1] != move) { - ss->reduction = Root ? reduction(depth, moveCount - MultiPV + 1) - : reduction(depth, moveCount); + ss->reduction = reduction(depth, moveCount); if (ss->reduction) { alpha = SpNode ? sp->alpha : alpha; @@ -1193,14 +1193,14 @@ split_point_start: // At split points actual search starts from here alpha = sp->alpha; } - if (!Root && value > bestValue && !(SpNode && ThreadsMgr.cutoff_at_splitpoint(threadID))) + if (value > bestValue && !(SpNode && ThreadsMgr.cutoff_at_splitpoint(threadID))) { bestValue = value; if (SpNode) sp->bestValue = value; - if (value > alpha) + if (!Root && value > alpha) { if (PvNode && value < beta) // We want always alpha < beta { @@ -1218,16 +1218,12 @@ split_point_start: // At split points actual search starts from here ss->bestMove = move; if (SpNode) - sp->parentSstack->bestMove = move; + sp->ss->bestMove = move; } } if (Root) { - // To avoid to exit with bestValue == -VALUE_INFINITE - if (value > bestValue) - bestValue = value; - // 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 @@ -1239,13 +1235,9 @@ split_point_start: // At split points actual search starts from here // Remember searched nodes counts for this move mp.rm->nodes += pos.nodes_searched() - nodes; - // Step 17. Check for new best move - if (!isPvMove && value <= alpha) - mp.rm->pv_score = -VALUE_INFINITE; - else + // PV move or new best move ? + if (isPvMove || value > alpha) { - // PV move or new best move! - // Update PV ss->bestMove = move; mp.rm->pv_score = value; @@ -1265,9 +1257,11 @@ split_point_start: // At split points actual search starts from here alpha = Rml[Min(moveCount, MultiPV) - 1].pv_score; // FIXME why moveCount? else if (value > alpha) alpha = value; + } + else + mp.rm->pv_score = -VALUE_INFINITE; - } // PV move or new best move - } + } // Root // Step 18. Check for split if ( !Root @@ -2116,16 +2110,19 @@ split_point_start: // At split points actual search starts from here threads[threadID].state = THREAD_SEARCHING; - // Here we call search() with SplitPoint template parameter set to true + // Copy SplitPoint position and search stack and call search() + // with SplitPoint template parameter set to true. + SearchStack ss[PLY_MAX_PLUS_2]; SplitPoint* tsp = threads[threadID].splitPoint; Position pos(*tsp->pos, threadID); - SearchStack* ss = tsp->sstack[threadID] + 1; - ss->sp = tsp; + + memcpy(ss, tsp->ss - 1, 4 * sizeof(SearchStack)); + (ss+1)->sp = tsp; if (tsp->pvNode) - search(pos, ss, tsp->alpha, tsp->beta, tsp->depth, tsp->ply); + search(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth, tsp->ply); else - search(pos, ss, tsp->alpha, tsp->beta, tsp->depth, tsp->ply); + search(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth, tsp->ply); assert(threads[threadID].state == THREAD_SEARCHING); @@ -2370,7 +2367,7 @@ split_point_start: // At split points actual search starts from here splitPoint.moveCount = moveCount; splitPoint.pos = &pos; splitPoint.nodes = 0; - splitPoint.parentSstack = ss; + splitPoint.ss = ss; for (i = 0; i < activeThreads; i++) splitPoint.slaves[i] = 0; @@ -2397,12 +2394,10 @@ split_point_start: // At split points actual search starts from here lock_release(&mpLock); // Tell the threads that they have work to do. This will make them leave - // their idle loop. But before copy search stack tail for each thread. + // their idle loop. for (i = 0; i < activeThreads; i++) if (i == master || splitPoint.slaves[i]) { - memcpy(splitPoint.sstack[i], ss - 1, 4 * sizeof(SearchStack)); - assert(i == master || threads[i].state == THREAD_BOOKED); threads[i].state = THREAD_WORKISWAITING; // This makes the slave to exit from idle_loop()