[refactor] Add helper functions and simplify thread selection

I found these changes useful and natural when working on a patch to improve mate reporting. I can revert some of the changes if maintainers would prefer that. E.g. I am not sure whether `unset_bound_flags()` is worth defining.

closes https://github.com/official-stockfish/Stockfish/pull/6785

No functional change
This commit is contained in:
Robert Nurnberg @ elitebook
2026-05-10 11:43:53 +02:00
committed by Joost VandeVondele
parent 6127bf711e
commit fcbd160d26
4 changed files with 40 additions and 33 deletions
+16 -21
View File
@@ -366,45 +366,40 @@ Thread* ThreadPool::get_best_thread() const {
for (auto&& th : threads)
votes[th->worker->rootMoves[0].pv[0]] += thread_voting_value(th.get());
auto has_bound = [](const Thread* th) {
return th->worker->rootMoves[0].scoreLowerbound || th->worker->rootMoves[0].scoreUpperbound;
};
for (auto&& th : threads)
{
const auto bestThreadScore = bestThread->worker->rootMoves[0].score;
const auto newThreadScore = th->worker->rootMoves[0].score;
const auto& bestThreadMove = bestThread->worker->rootMoves[0];
const auto& newThreadMove = th->worker->rootMoves[0];
const auto& bestThreadPV = bestThread->worker->rootMoves[0].pv;
const auto& newThreadPV = th->worker->rootMoves[0].pv;
const auto bestThreadMoveVote = votes[bestThreadPV[0]];
const auto newThreadMoveVote = votes[newThreadPV[0]];
const auto bestThreadMoveVote = votes[bestThreadMove.pv[0]];
const auto newThreadMoveVote = votes[newThreadMove.pv[0]];
// Aborted (d1) searches may lead to inexact win (or loss) scores.
const bool bestThreadDecisive = bestThreadScore != -VALUE_INFINITE
&& is_decisive(bestThreadScore) && !has_bound(bestThread);
const bool newThreadDecisive =
newThreadScore != -VALUE_INFINITE && is_decisive(newThreadScore) && !has_bound(th.get());
const bool bestThreadDecisive = bestThreadMove.score != -VALUE_INFINITE
&& is_decisive(bestThreadMove.score)
&& !bestThreadMove.score_is_bound();
const bool newThreadDecisive = newThreadMove.score != -VALUE_INFINITE
&& is_decisive(newThreadMove.score)
&& !newThreadMove.score_is_bound();
// We make sure not to pick a thread with a truncated principal variation.
const bool betterVotingValue =
thread_voting_value(th.get()) * int(newThreadPV.size() > 2)
> thread_voting_value(bestThread) * int(bestThreadPV.size() > 2);
thread_voting_value(th.get()) * int(newThreadMove.pv.size() > 2)
> thread_voting_value(bestThread) * int(bestThreadMove.pv.size() > 2);
if (bestThreadDecisive)
{
// Make sure we pick the shortest mate / TB conversion.
if (newThreadDecisive && std::abs(newThreadScore) > std::abs(bestThreadScore))
if (newThreadDecisive && std::abs(newThreadMove.score) > std::abs(bestThreadMove.score))
{
assert((is_win(bestThreadScore) && is_win(newThreadScore))
|| (is_loss(bestThreadScore) && is_loss(newThreadScore)));
assert((is_win(bestThreadMove.score) && is_win(newThreadMove.score))
|| (is_loss(bestThreadMove.score) && is_loss(newThreadMove.score)));
bestThread = th.get();
}
}
else if (newThreadDecisive
|| (!is_loss(newThreadScore)
|| (!is_loss(newThreadMove.score)
&& (newThreadMoveVote > bestThreadMoveVote
|| (newThreadMoveVote == bestThreadMoveVote && betterVotingValue))))
bestThread = th.get();