Skip to content

Commit

Permalink
Set timer to a fixed interval
Browse files Browse the repository at this point in the history
And remove a complex (and broken) formula.

Indeed previous code was broken in case of TC with big
time increments where available_time() was too similar
to total time yielding to many time losses, so for instance:

go wtime 2600 winc 2600
info nodes 4432770 time 2601 <-- time forfeit!

maximum search time = 2530 ms
available_time = 2300 ms

For a reference and further details see:

https://groups.google.com/forum/?fromgroups=#!topic/fishcooking/dCPAvQDcm2E

Speed tested with bench disabling timer alltogheter vs timer set at
max resolution, showed we have no speed regressions both in single
core and when using all physical cores.

No functional change.
  • Loading branch information
mcostalba committed Nov 1, 2013
1 parent e8f9447 commit a3a0df9
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 17 deletions.
16 changes: 3 additions & 13 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ namespace {
// Set to true to force running with one thread. Used for debugging
const bool FakeSplit = false;

// This is the minimum interval in msec between two check_time() calls
const int TimerResolution = 5;

// Different node types, used as template parameter
enum NodeType { Root, PV, NonPV, SplitPointRoot, SplitPointPV, SplitPointNonPV };

Expand Down Expand Up @@ -243,19 +240,12 @@ void Search::think() {
Threads[i]->maxPly = 0;

Threads.sleepWhileIdle = Options["Idle Threads Sleep"];

// Set best timer interval to avoid lagging under time pressure. Timer is
// used to check for remaining available thinking time.
Threads.timer->msec =
Limits.use_time_management() ? std::min(100, std::max(TimeMgr.available_time() / 16, TimerResolution)) :
Limits.nodes ? 2 * TimerResolution
: 100;

Threads.timer->run = true;
Threads.timer->notify_one(); // Wake up the recurring timer

id_loop(RootPos); // Let's start searching !

Threads.timer->msec = 0; // Stop the timer
Threads.timer->run = false; // Stop the timer
Threads.sleepWhileIdle = true; // Send idle threads to sleep

if (Options["Write Search Log"])
Expand Down Expand Up @@ -1764,7 +1754,7 @@ void check_time() {
&& !Signals.failedLowAtRoot
&& elapsed > TimeMgr.available_time();

bool noMoreTime = elapsed > TimeMgr.maximum_time() - 2 * TimerResolution
bool noMoreTime = elapsed > TimeMgr.maximum_time() - 2 * TimerThread::Resolution
|| stillAtFirstMove;

if ( (Limits.use_time_management() && noMoreTime)
Expand Down
4 changes: 2 additions & 2 deletions src/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ void TimerThread::idle_loop() {
mutex.lock();

if (!exit)
sleepCondition.wait_for(mutex, msec ? msec : INT_MAX);
sleepCondition.wait_for(mutex, run ? Resolution : INT_MAX);

mutex.unlock();

if (msec)
if (run)
check_time();
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,10 @@ struct MainThread : public Thread {
};

struct TimerThread : public ThreadBase {
TimerThread() : msec(0) {}
TimerThread() : run(false) {}
virtual void idle_loop();
int msec;
bool run;
static const int Resolution = 5; // msec between two check_time() calls
};


Expand Down

0 comments on commit a3a0df9

Please sign in to comment.