mirror of
https://github.com/sockspls/badfish
synced 2025-05-02 17:49:35 +00:00
Try hard not to lose on time
We try hard not to lose on time even under extreme time pressure. We achieve this through 3 different but coordinated steps: 1) Increase max frequency of timer events 2) Quickly return after a stop signal 3) Take in account timer resolution With these SF played under LittleBlitzer at 1"+0.02 and 3"+0 without losing on time even one game. No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
d282cf6964
commit
f80c50bcdd
4 changed files with 17 additions and 13 deletions
|
@ -139,6 +139,9 @@ namespace {
|
||||||
// better than the second best move.
|
// better than the second best move.
|
||||||
const Value EasyMoveMargin = Value(0x150);
|
const Value EasyMoveMargin = Value(0x150);
|
||||||
|
|
||||||
|
// This is the minimum interval in msec between two check_time() calls
|
||||||
|
const int TimerResolution = 5;
|
||||||
|
|
||||||
|
|
||||||
/// Namespace variables
|
/// Namespace variables
|
||||||
|
|
||||||
|
@ -343,8 +346,8 @@ void Search::think() {
|
||||||
|
|
||||||
// Set best timer interval to avoid lagging under time pressure. Timer is
|
// Set best timer interval to avoid lagging under time pressure. Timer is
|
||||||
// used to check for remaining available thinking time.
|
// used to check for remaining available thinking time.
|
||||||
if (TimeMgr.available_time())
|
if (Limits.use_time_management())
|
||||||
Threads.set_timer(std::min(100, std::max(TimeMgr.available_time() / 8, 20)));
|
Threads.set_timer(std::min(100, std::max(TimeMgr.available_time() / 16, TimerResolution)));
|
||||||
else
|
else
|
||||||
Threads.set_timer(100);
|
Threads.set_timer(100);
|
||||||
|
|
||||||
|
@ -513,7 +516,7 @@ namespace {
|
||||||
bestMoveNeverChanged = false;
|
bestMoveNeverChanged = false;
|
||||||
|
|
||||||
// Do we have time for the next iteration? Can we stop searching now?
|
// Do we have time for the next iteration? Can we stop searching now?
|
||||||
if (!Signals.stop && !Signals.stopOnPonderhit && Limits.useTimeManagement())
|
if (!Signals.stop && !Signals.stopOnPonderhit && Limits.use_time_management())
|
||||||
{
|
{
|
||||||
bool stop = false; // Local variable, not the volatile Signals.stop
|
bool stop = false; // Local variable, not the volatile Signals.stop
|
||||||
|
|
||||||
|
@ -865,7 +868,8 @@ split_point_start: // At split points actual search starts from here
|
||||||
// Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
|
// Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
|
||||||
while ( bestValue < beta
|
while ( bestValue < beta
|
||||||
&& (move = mp.next_move()) != MOVE_NONE
|
&& (move = mp.next_move()) != MOVE_NONE
|
||||||
&& !thread.cutoff_occurred())
|
&& !thread.cutoff_occurred()
|
||||||
|
&& !Signals.stop)
|
||||||
{
|
{
|
||||||
assert(is_ok(move));
|
assert(is_ok(move));
|
||||||
|
|
||||||
|
@ -1957,11 +1961,11 @@ void Thread::idle_loop(SplitPoint* sp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// do_timer_event() is called by the timer thread when the timer triggers. It
|
/// check_time() is called by the timer thread when the timer triggers. It is
|
||||||
/// is used to print debug info and, more important, to detect when we are out of
|
/// used to print debug info and, more important, to detect when we are out of
|
||||||
/// available time and so stop the search.
|
/// available time and so stop the search.
|
||||||
|
|
||||||
void do_timer_event() {
|
void check_time() {
|
||||||
|
|
||||||
static int lastInfoTime;
|
static int lastInfoTime;
|
||||||
int e = elapsed_time();
|
int e = elapsed_time();
|
||||||
|
@ -1979,10 +1983,10 @@ void do_timer_event() {
|
||||||
&& !Signals.failedLowAtRoot
|
&& !Signals.failedLowAtRoot
|
||||||
&& e > TimeMgr.available_time();
|
&& e > TimeMgr.available_time();
|
||||||
|
|
||||||
bool noMoreTime = e > TimeMgr.maximum_time()
|
bool noMoreTime = e > TimeMgr.maximum_time() - TimerResolution
|
||||||
|| stillAtFirstMove;
|
|| stillAtFirstMove;
|
||||||
|
|
||||||
if ( (Limits.useTimeManagement() && noMoreTime)
|
if ( (Limits.use_time_management() && noMoreTime)
|
||||||
|| (Limits.maxTime && e >= Limits.maxTime)
|
|| (Limits.maxTime && e >= Limits.maxTime)
|
||||||
/* missing nodes limit */ ) // FIXME
|
/* missing nodes limit */ ) // FIXME
|
||||||
Signals.stop = true;
|
Signals.stop = true;
|
||||||
|
|
|
@ -55,7 +55,7 @@ struct Stack {
|
||||||
struct LimitsType {
|
struct LimitsType {
|
||||||
|
|
||||||
LimitsType() { memset(this, 0, sizeof(LimitsType)); }
|
LimitsType() { memset(this, 0, sizeof(LimitsType)); }
|
||||||
bool useTimeManagement() const { return !(maxTime | maxDepth | maxNodes | infinite); }
|
bool use_time_management() const { return !(maxTime | maxDepth | maxNodes | infinite); }
|
||||||
|
|
||||||
int time, increment, movesToGo, maxTime, maxDepth, maxNodes, infinite, ponder;
|
int time, increment, movesToGo, maxTime, maxDepth, maxNodes, infinite, ponder;
|
||||||
};
|
};
|
||||||
|
|
|
@ -367,7 +367,7 @@ template Value ThreadsManager::split<true>(Position&, Stack*, Value, Value, Valu
|
||||||
|
|
||||||
// Thread::timer_loop() is where the timer thread waits maxPly milliseconds and
|
// Thread::timer_loop() is where the timer thread waits maxPly milliseconds and
|
||||||
// then calls do_timer_event(). If maxPly is 0 thread sleeps until is woken up.
|
// then calls do_timer_event(). If maxPly is 0 thread sleeps until is woken up.
|
||||||
extern void do_timer_event();
|
extern void check_time();
|
||||||
|
|
||||||
void Thread::timer_loop() {
|
void Thread::timer_loop() {
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ void Thread::timer_loop() {
|
||||||
lock_grab(&sleepLock);
|
lock_grab(&sleepLock);
|
||||||
timed_wait(&sleepCond, &sleepLock, maxPly ? maxPly : INT_MAX);
|
timed_wait(&sleepCond, &sleepLock, maxPly ? maxPly : INT_MAX);
|
||||||
lock_release(&sleepLock);
|
lock_release(&sleepLock);
|
||||||
do_timer_event();
|
check_time();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ OptionsMap::OptionsMap() {
|
||||||
o["OwnBook"] = UCIOption(true);
|
o["OwnBook"] = UCIOption(true);
|
||||||
o["MultiPV"] = UCIOption(1, 1, 500);
|
o["MultiPV"] = UCIOption(1, 1, 500);
|
||||||
o["Skill Level"] = UCIOption(20, 0, 20);
|
o["Skill Level"] = UCIOption(20, 0, 20);
|
||||||
o["Emergency Move Horizon"] = UCIOption(40, 0, 50);
|
o["Emergency Move Horizon"] = UCIOption(30, 0, 50);
|
||||||
o["Emergency Base Time"] = UCIOption(200, 0, 30000);
|
o["Emergency Base Time"] = UCIOption(200, 0, 30000);
|
||||||
o["Emergency Move Time"] = UCIOption(70, 0, 5000);
|
o["Emergency Move Time"] = UCIOption(70, 0, 5000);
|
||||||
o["Minimum Thinking Time"] = UCIOption(20, 0, 5000);
|
o["Minimum Thinking Time"] = UCIOption(20, 0, 5000);
|
||||||
|
|
Loading…
Add table
Reference in a new issue