X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=28e231dd98a0811529b165e14b1671e3d6e47fae;hp=fa12ee7109c77ad66b4f02eb8b65acc6379205a8;hb=50edb7cd7353e24e17da8f428e4b12375cf684f7;hpb=875a8079bc142ca92027b07427d72c03fe5268a5 diff --git a/src/search.cpp b/src/search.cpp index fa12ee71..28e231dd 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -307,11 +307,7 @@ void Search::think() { << endl; } - for (int i = 0; i < Threads.size(); i++) - { - Threads[i].maxPly = 0; - Threads[i].wake_up(); - } + Threads.set_size(Options["Threads"]); // Set best timer interval to avoid lagging under time pressure. Timer is // used to check for remaining available thinking time. @@ -348,7 +344,7 @@ finalize: // but if we are pondering or in infinite search, we shouldn't print the best // move before we are told to do so. if (!Signals.stop && (Limits.ponder || Limits.infinite)) - Threads.wait_for_stop_or_ponderhit(); + Threads[pos.thread()].wait_for_stop_or_ponderhit(); // Best move could be MOVE_NONE when searching on a stalemate position cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], Chess960) @@ -467,7 +463,7 @@ namespace { if (SkillLevelEnabled && depth == 1 + SkillLevel) skillBest = do_skill_level(); - if (Options["Use Search Log"]) + if (!Signals.stop && Options["Use Search Log"]) pv_info_to_log(pos, depth, bestValue, elapsed_time(), &RootMoves[0].pv[0]); // Filter out startup noise when monitoring best move stability @@ -1061,7 +1057,9 @@ split_point_start: // At split points actual search starts from here sp->bestValue = value; sp->ss->bestMove = move; sp->alpha = alpha; - sp->is_betaCutoff = (value >= beta); + + if (value >= beta) + sp->cutoff = true; } } @@ -1282,12 +1280,7 @@ split_point_start: // At split points actual search starts from here && !pos.is_capture_or_promotion(move) && ss->eval + PawnValueMidgame / 4 < beta && !check_is_dangerous(pos, move, futilityBase, beta, &bestValue)) - { - if (ss->eval + PawnValueMidgame / 4 > bestValue) - bestValue = ss->eval + PawnValueMidgame / 4; - continue; - } // Check for legality only before to do the move if (!pos.pl_move_is_legal(move, ci.pinned)) @@ -1350,7 +1343,7 @@ split_point_start: // At split points actual search starts from here them = ~pos.side_to_move(); ksq = pos.king_square(them); kingAtt = pos.attacks_from(ksq); - pc = pos.piece_on(from); + pc = pos.piece_moved(move); occ = pos.occupied_squares() & ~(1ULL << from) & ~(1ULL << ksq); oldAtt = pos.attacks_from(pc, from, occ); @@ -1363,8 +1356,7 @@ split_point_start: // At split points actual search starts from here return true; // Rule 2. Queen contact check is very dangerous - if ( type_of(pc) == QUEEN - && bit_is_set(kingAtt, to)) + if (type_of(pc) == QUEEN && (kingAtt & to)) return true; // Rule 3. Creating new double threats with checks @@ -1419,23 +1411,21 @@ split_point_start: // At split points actual search starts from here // Case 3: Moving through the vacated square p2 = pos.piece_on(f2); - if ( piece_is_slider(p2) - && bit_is_set(squares_between(f2, t2), f1)) + if (piece_is_slider(p2) && (squares_between(f2, t2) & f1)) return true; // Case 4: The destination square for m2 is defended by the moving piece in m1 p1 = pos.piece_on(t1); - if (bit_is_set(pos.attacks_from(p1, t1), t2)) + if (pos.attacks_from(p1, t1) & t2) return true; // Case 5: Discovered check, checking piece is the piece moved in m1 ksq = pos.king_square(pos.side_to_move()); - if ( piece_is_slider(p1) - && bit_is_set(squares_between(t1, ksq), f2)) + if (piece_is_slider(p1) && (squares_between(t1, ksq) & f2)) { Bitboard occ = pos.occupied_squares(); - xor_bit(&occ, f2); - if (bit_is_set(pos.attacks_from(p1, t1, occ), ksq)) + occ ^= f2; + if (pos.attacks_from(p1, t1, occ) & ksq) return true; } return false; @@ -1505,9 +1495,9 @@ split_point_start: // At split points actual search starts from here // Case 3: If the moving piece in the threatened move is a slider, don't // prune safe moves which block its ray. - if ( piece_is_slider(pos.piece_on(tfrom)) - && bit_is_set(squares_between(tfrom, tto), mto) - && pos.see_sign(m) >= 0) + if ( piece_is_slider(pos.piece_on(tfrom)) + && (squares_between(tfrom, tto) & mto) + && pos.see_sign(m) >= 0) return true; return false; @@ -1777,14 +1767,14 @@ void RootMove::extract_pv_from_tt(Position& pos) { pos.do_move(m, *st++); while ( (tte = TT.probe(pos.key())) != NULL - && tte->move() != MOVE_NONE - && pos.is_pseudo_legal(tte->move()) - && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces()) + && (m = tte->move()) != MOVE_NONE // Local copy, TT entry could change + && pos.is_pseudo_legal(m) + && pos.pl_move_is_legal(m, pos.pinned_pieces()) && ply < MAX_PLY && (!pos.is_draw() || ply < 2)) { - pv.push_back(tte->move()); - pos.do_move(tte->move(), *st++); + pv.push_back(m); + pos.do_move(m, *st++); ply++; } pv.push_back(MOVE_NONE); @@ -1872,10 +1862,16 @@ void Thread::idle_loop(SplitPoint* sp_master) { { assert(!do_sleep && !do_exit); - // Copy split point position and search stack and call search() + lock_grab(Threads.splitLock); + + assert(is_searching); + SplitPoint* sp = curSplitPoint; + + lock_release(Threads.splitLock); + Stack ss[MAX_PLY_PLUS_2]; - SplitPoint* sp = splitPoint; Position pos(*sp->pos, threadID); + int master = sp->master; memcpy(ss, sp->ss - 1, 4 * sizeof(Stack)); (ss+1)->sp = sp; @@ -1893,19 +1889,21 @@ void Thread::idle_loop(SplitPoint* sp_master) { assert(is_searching); - // We return from search with lock held + is_searching = false; sp->slavesMask &= ~(1ULL << threadID); sp->nodes += pos.nodes_searched(); - lock_release(sp->lock); - is_searching = false; + // After releasing the lock we cannot access anymore any SplitPoint + // related data in a reliably way becuase it could have been released + // under our feet by the sp master. + lock_release(sp->lock); // Wake up master thread so to allow it to return from the idle loop in // case we are the last slave of the split point. if ( Threads.use_sleeping_threads() - && threadID != sp->master - && !Threads[sp->master].is_searching) - Threads[sp->master].wake_up(); + && threadID != master + && !Threads[master].is_searching) + Threads[master].wake_up(); } } }