mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-20 00:56:39 +08:00
Reformat threads code
Apart from some renaming the biggest change is the retire of split_point_finished() replaced by slavesMask flags. As a side effect we now take also split point lock when allocation available threads. No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
108
src/search.cpp
108
src/search.cpp
@@ -573,19 +573,25 @@ namespace {
|
||||
thread.maxPly = ss->ply;
|
||||
|
||||
// Step 1. Initialize node
|
||||
if (!SpNode)
|
||||
if (SpNode)
|
||||
{
|
||||
tte = NULL;
|
||||
ttMove = excludedMove = MOVE_NONE;
|
||||
sp = ss->sp;
|
||||
threatMove = sp->threatMove;
|
||||
bestValue = sp->bestValue;
|
||||
moveCount = sp->moveCount; // Lock must be held here
|
||||
|
||||
assert(bestValue > -VALUE_INFINITE && moveCount > 0);
|
||||
|
||||
goto split_point_start;
|
||||
}
|
||||
else
|
||||
{
|
||||
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] = MOVE_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp = ss->sp;
|
||||
tte = NULL;
|
||||
ttMove = excludedMove = MOVE_NONE;
|
||||
threatMove = sp->threatMove;
|
||||
goto split_point_start;
|
||||
|
||||
}
|
||||
|
||||
// Step 2. Check for aborted search and immediate draw
|
||||
@@ -820,14 +826,6 @@ split_point_start: // At split points actual search starts from here
|
||||
&& !excludedMove // Recursive singular search is not allowed
|
||||
&& (tte->type() & VALUE_TYPE_LOWER)
|
||||
&& tte->depth() >= depth - 3 * ONE_PLY;
|
||||
if (SpNode)
|
||||
{
|
||||
lock_grab(sp->lock);
|
||||
bestValue = sp->bestValue;
|
||||
moveCount = sp->moveCount;
|
||||
|
||||
assert(bestValue > -VALUE_INFINITE && moveCount > 0);
|
||||
}
|
||||
|
||||
// Step 11. Loop through moves
|
||||
// Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
|
||||
@@ -1129,14 +1127,6 @@ split_point_start: // At split points actual search starts from here
|
||||
}
|
||||
}
|
||||
|
||||
if (SpNode)
|
||||
{
|
||||
// Here we have the lock still grabbed
|
||||
sp->is_slave[pos.thread()] = false;
|
||||
sp->nodes += pos.nodes_searched();
|
||||
lock_release(sp->lock);
|
||||
}
|
||||
|
||||
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
||||
|
||||
return bestValue;
|
||||
@@ -1836,24 +1826,24 @@ void RootMove::insert_pv_in_tt(Position& pos) {
|
||||
|
||||
|
||||
/// Thread::idle_loop() is where the thread is parked when it has no work to do.
|
||||
/// The parameter 'sp', if non-NULL, is a pointer to an active SplitPoint object
|
||||
/// for which the thread is the master.
|
||||
/// The parameter 'master_sp', if non-NULL, is a pointer to an active SplitPoint
|
||||
/// object for which the thread is the master.
|
||||
|
||||
void Thread::idle_loop(SplitPoint* sp) {
|
||||
void Thread::idle_loop(SplitPoint* sp_master) {
|
||||
|
||||
while (true)
|
||||
// If this thread is the master of a split point and all slaves have
|
||||
// finished their work at this split point, return from the idle loop.
|
||||
while (!sp_master || sp_master->slavesMask)
|
||||
{
|
||||
// If we are not searching, wait for a condition to be signaled
|
||||
// instead of wasting CPU time polling for work.
|
||||
while ( do_sleep
|
||||
|| do_terminate
|
||||
|| (Threads.use_sleeping_threads() && !is_searching))
|
||||
|| do_exit
|
||||
|| (!is_searching && Threads.use_sleeping_threads()))
|
||||
{
|
||||
assert((!sp && threadID) || Threads.use_sleeping_threads());
|
||||
|
||||
if (do_terminate)
|
||||
if (do_exit)
|
||||
{
|
||||
assert(!sp);
|
||||
assert(!sp_master);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1861,7 +1851,7 @@ void Thread::idle_loop(SplitPoint* sp) {
|
||||
lock_grab(sleepLock);
|
||||
|
||||
// If we are master and all slaves have finished don't go to sleep
|
||||
if (sp && Threads.split_point_finished(sp))
|
||||
if (sp_master && !sp_master->slavesMask)
|
||||
{
|
||||
lock_release(sleepLock);
|
||||
break;
|
||||
@@ -1880,46 +1870,42 @@ void Thread::idle_loop(SplitPoint* sp) {
|
||||
// If this thread has been assigned work, launch a search
|
||||
if (is_searching)
|
||||
{
|
||||
assert(!do_terminate);
|
||||
assert(!do_sleep && !do_exit);
|
||||
|
||||
// Copy split point position and search stack and call search()
|
||||
Stack ss[MAX_PLY_PLUS_2];
|
||||
SplitPoint* tsp = splitPoint;
|
||||
Position pos(*tsp->pos, threadID);
|
||||
SplitPoint* sp = splitPoint;
|
||||
Position pos(*sp->pos, threadID);
|
||||
|
||||
memcpy(ss, tsp->ss - 1, 4 * sizeof(Stack));
|
||||
(ss+1)->sp = tsp;
|
||||
memcpy(ss, sp->ss - 1, 4 * sizeof(Stack));
|
||||
(ss+1)->sp = sp;
|
||||
|
||||
if (tsp->nodeType == Root)
|
||||
search<SplitPointRoot>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth);
|
||||
else if (tsp->nodeType == PV)
|
||||
search<SplitPointPV>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth);
|
||||
else if (tsp->nodeType == NonPV)
|
||||
search<SplitPointNonPV>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth);
|
||||
lock_grab(sp->lock);
|
||||
|
||||
if (sp->nodeType == Root)
|
||||
search<SplitPointRoot>(pos, ss+1, sp->alpha, sp->beta, sp->depth);
|
||||
else if (sp->nodeType == PV)
|
||||
search<SplitPointPV>(pos, ss+1, sp->alpha, sp->beta, sp->depth);
|
||||
else if (sp->nodeType == NonPV)
|
||||
search<SplitPointNonPV>(pos, ss+1, sp->alpha, sp->beta, sp->depth);
|
||||
else
|
||||
assert(false);
|
||||
|
||||
assert(is_searching);
|
||||
|
||||
// We return from search with lock held
|
||||
sp->slavesMask &= ~(1ULL << threadID);
|
||||
sp->nodes += pos.nodes_searched();
|
||||
lock_release(sp->lock);
|
||||
|
||||
is_searching = false;
|
||||
|
||||
// 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 != tsp->master
|
||||
&& !Threads[tsp->master].is_searching)
|
||||
Threads[tsp->master].wake_up();
|
||||
}
|
||||
|
||||
// If this thread is the master of a split point and all slaves have
|
||||
// finished their work at this split point, return from the idle loop.
|
||||
if (sp && Threads.split_point_finished(sp))
|
||||
{
|
||||
// Because sp->is_slave[] is reset under lock protection,
|
||||
// be sure sp->lock has been released before to return.
|
||||
lock_grab(sp->lock);
|
||||
lock_release(sp->lock);
|
||||
return;
|
||||
&& threadID != sp->master
|
||||
&& !Threads[sp->master].is_searching)
|
||||
Threads[sp->master].wake_up();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user