mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-21 17:46:26 +08:00
Refactor some threads related code.
This is a code style change that moves some pure thread code into the threads class.
It is a bit more code, but it makes search.cpp cleaner and easier to read by hiding some thread specific functionality.
STC (SMP)
LLR: 2.93 (-2.94,2.94) {-1.50,0.50}
Total: 75896 W: 12073 L: 12026 D: 51797
Ptnml(0-2): 828, 8224, 19872, 8121, 903
https://tests.stockfishchess.org/tests/view/5ed492e8f29b40b0fc95a74c
closes https://github.com/official-stockfish/Stockfish/pull/2720
No functional change.
This commit is contained in:
committed by
Joost VandeVondele
parent
b0eb5a1ba3
commit
1c65310c0e
@@ -236,14 +236,8 @@ void MainThread::search() {
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Thread* th : Threads)
|
||||
{
|
||||
th->bestMoveChanges = 0;
|
||||
if (th != this)
|
||||
th->start_searching();
|
||||
}
|
||||
|
||||
Thread::search(); // Let's start searching!
|
||||
Threads.start_searching(); // start non-main threads
|
||||
Thread::search(); // main thread start searching
|
||||
}
|
||||
|
||||
// When we reach the maximum depth, we can arrive here without a raise of
|
||||
@@ -260,9 +254,7 @@ void MainThread::search() {
|
||||
Threads.stop = true;
|
||||
|
||||
// Wait until all threads have finished
|
||||
for (Thread* th : Threads)
|
||||
if (th != this)
|
||||
th->wait_for_search_finished();
|
||||
Threads.wait_for_search_finished();
|
||||
|
||||
// When playing in 'nodes as time' mode, subtract the searched nodes from
|
||||
// the available ones before exiting.
|
||||
@@ -271,37 +263,11 @@ void MainThread::search() {
|
||||
|
||||
Thread* bestThread = this;
|
||||
|
||||
// Check if there are threads with a better score than main thread
|
||||
if ( int(Options["MultiPV"]) == 1
|
||||
&& !Limits.depth
|
||||
&& !(Skill(Options["Skill Level"]).enabled() || int(Options["UCI_LimitStrength"]))
|
||||
&& rootMoves[0].pv[0] != MOVE_NONE)
|
||||
{
|
||||
std::map<Move, int64_t> votes;
|
||||
Value minScore = this->rootMoves[0].score;
|
||||
|
||||
// Find minimum score
|
||||
for (Thread* th: Threads)
|
||||
minScore = std::min(minScore, th->rootMoves[0].score);
|
||||
|
||||
// Vote according to score and depth, and select the best thread
|
||||
for (Thread* th : Threads)
|
||||
{
|
||||
votes[th->rootMoves[0].pv[0]] +=
|
||||
(th->rootMoves[0].score - minScore + 14) * int(th->completedDepth);
|
||||
|
||||
if (abs(bestThread->rootMoves[0].score) >= VALUE_TB_WIN_IN_MAX_PLY)
|
||||
{
|
||||
// Make sure we pick the shortest mate / TB conversion or stave off mate the longest
|
||||
if (th->rootMoves[0].score > bestThread->rootMoves[0].score)
|
||||
bestThread = th;
|
||||
}
|
||||
else if ( th->rootMoves[0].score >= VALUE_TB_WIN_IN_MAX_PLY
|
||||
|| ( th->rootMoves[0].score > VALUE_TB_LOSS_IN_MAX_PLY
|
||||
&& votes[th->rootMoves[0].pv[0]] > votes[bestThread->rootMoves[0].pv[0]]))
|
||||
bestThread = th;
|
||||
}
|
||||
}
|
||||
if (int(Options["MultiPV"]) == 1 &&
|
||||
!Limits.depth &&
|
||||
!(Skill(Options["Skill Level"]).enabled() || int(Options["UCI_LimitStrength"])) &&
|
||||
rootMoves[0].pv[0] != MOVE_NONE)
|
||||
bestThread = Threads.get_best_thread();
|
||||
|
||||
bestPreviousScore = bestThread->rootMoves[0].score;
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ void ThreadPool::start_thinking(Position& pos, StateListPtr& states,
|
||||
|
||||
for (Thread* th : *this)
|
||||
{
|
||||
th->nodes = th->tbHits = th->nmpMinPly = 0;
|
||||
th->nodes = th->tbHits = th->nmpMinPly = th->bestMoveChanges = 0;
|
||||
th->rootDepth = th->completedDepth = 0;
|
||||
th->rootMoves = rootMoves;
|
||||
th->rootPos.set(pos.fen(), pos.is_chess960(), &setupStates->back(), th);
|
||||
@@ -218,3 +218,52 @@ void ThreadPool::start_thinking(Position& pos, StateListPtr& states,
|
||||
|
||||
main()->start_searching();
|
||||
}
|
||||
|
||||
Thread* ThreadPool::get_best_thread() const {
|
||||
|
||||
Thread* bestThread = front();
|
||||
std::map<Move, int64_t> votes;
|
||||
Value minScore = VALUE_NONE;
|
||||
|
||||
// Find minimum score of all threads
|
||||
for (Thread* th: *this)
|
||||
minScore = std::min(minScore, th->rootMoves[0].score);
|
||||
|
||||
// Vote according to score and depth, and select the best thread
|
||||
for (Thread* th : *this)
|
||||
{
|
||||
votes[th->rootMoves[0].pv[0]] +=
|
||||
(th->rootMoves[0].score - minScore + 14) * int(th->completedDepth);
|
||||
|
||||
if (abs(bestThread->rootMoves[0].score) >= VALUE_TB_WIN_IN_MAX_PLY)
|
||||
{
|
||||
// Make sure we pick the shortest mate / TB conversion or stave off mate the longest
|
||||
if (th->rootMoves[0].score > bestThread->rootMoves[0].score)
|
||||
bestThread = th;
|
||||
}
|
||||
else if ( th->rootMoves[0].score >= VALUE_TB_WIN_IN_MAX_PLY
|
||||
|| ( th->rootMoves[0].score > VALUE_TB_LOSS_IN_MAX_PLY
|
||||
&& votes[th->rootMoves[0].pv[0]] > votes[bestThread->rootMoves[0].pv[0]]))
|
||||
bestThread = th;
|
||||
}
|
||||
|
||||
return bestThread;
|
||||
}
|
||||
|
||||
/// Start non-main threads.
|
||||
|
||||
void ThreadPool::start_searching() {
|
||||
|
||||
for (Thread* th : *this)
|
||||
if (th != front())
|
||||
th->start_searching();
|
||||
}
|
||||
|
||||
/// Wait for non-main threads.
|
||||
|
||||
void ThreadPool::wait_for_search_finished() const {
|
||||
|
||||
for (Thread* th : *this)
|
||||
if (th != front())
|
||||
th->wait_for_search_finished();
|
||||
}
|
||||
|
||||
@@ -109,6 +109,9 @@ struct ThreadPool : public std::vector<Thread*> {
|
||||
MainThread* main() const { return static_cast<MainThread*>(front()); }
|
||||
uint64_t nodes_searched() const { return accumulate(&Thread::nodes); }
|
||||
uint64_t tb_hits() const { return accumulate(&Thread::tbHits); }
|
||||
Thread* get_best_thread() const;
|
||||
void start_searching();
|
||||
void wait_for_search_finished() const;
|
||||
|
||||
std::atomic_bool stop, increaseDepth;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user