Skip to content

Commit

Permalink
Do not sleep, but yield
Browse files Browse the repository at this point in the history
During the search, do not block on condition variable, but instead use std::this_thread::yield().

Clear gain with 16 threads. Again results vary highly depending on hardware, but on average it's a clear gain.

ELO: 12.17 +-4.3 (95%) LOS: 100.0%
Total: 7998 W: 1407 L: 1127 D: 5464

There is no functional change in single thread mode

Resolves #294
  • Loading branch information
zamar committed Mar 15, 2015
1 parent a4b98a0 commit f04f50b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 28 deletions.
43 changes: 18 additions & 25 deletions src/search.cpp
Expand Up @@ -1595,8 +1595,25 @@ void Thread::idle_loop() {

assert(!this_sp || (this_sp->master == this && searching));

while (!exit)
while ( !exit
&& !(this_sp && this_sp->slavesMask.none()))
{
// If there is nothing to do, sleep.
while( !exit
&& !(this_sp && this_sp->slavesMask.none())
&& !searching)
{
if ( !this_sp
&& !Threads.main()->thinking)
{
std::unique_lock<Mutex> lk(mutex);
while (!exit && !Threads.main()->thinking)
sleepCondition.wait(lk);
}
else
std::this_thread::yield();
}

// If this thread has been assigned work, launch a search
while (searching)
{
Expand Down Expand Up @@ -1639,15 +1656,6 @@ void Thread::idle_loop() {
sp->allSlavesSearching = false;
sp->nodes += pos.nodes_searched();

// Wake up the master thread so to allow it to return from the idle
// loop in case we are the last slave of the split point.
if (this != sp->master && sp->slavesMask.none())
{
assert(!sp->master->searching);

sp->master->notify_one();
}

// After releasing the lock we can't access any SplitPoint related data
// in a safe way because it could have been released under our feet by
// the sp master.
Expand Down Expand Up @@ -1711,21 +1719,6 @@ void Thread::idle_loop() {
sp->mutex.unlock();
}
}

// Avoid races with notify_one() fired from last slave of the split point
std::unique_lock<Mutex> lk(mutex);

// If we are master and all slaves have finished then exit idle_loop
if (this_sp && this_sp->slavesMask.none())
{
assert(!searching);
break;
}

// If we are not searching, wait for a condition to be signaled instead of
// wasting CPU time polling for work.
if (!searching && !exit)
sleepCondition.wait(lk);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/thread.cpp
Expand Up @@ -184,8 +184,6 @@ void Thread::split(Position& pos, Stack* ss, Value alpha, Value beta, Value* bes
}

slave->allocMutex.unlock();

slave->notify_one(); // Could be sleeping
}

// Everything is set up. The master thread enters the idle loop, from which
Expand Down Expand Up @@ -375,5 +373,7 @@ void ThreadPool::start_thinking(const Position& pos, const LimitsType& limits,
RootMoves.push_back(RootMove(m));

main()->thinking = true;
main()->notify_one(); // Starts main thread

for (Thread* th : *this)
th->notify_one();
}

0 comments on commit f04f50b

Please sign in to comment.