mirror of
https://github.com/sockspls/badfish
synced 2025-05-01 01:03:09 +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.
|
||||
const Value EasyMoveMargin = Value(0x150);
|
||||
|
||||
// This is the minimum interval in msec between two check_time() calls
|
||||
const int TimerResolution = 5;
|
||||
|
||||
|
||||
/// Namespace variables
|
||||
|
||||
|
@ -343,8 +346,8 @@ void Search::think() {
|
|||
|
||||
// Set best timer interval to avoid lagging under time pressure. Timer is
|
||||
// used to check for remaining available thinking time.
|
||||
if (TimeMgr.available_time())
|
||||
Threads.set_timer(std::min(100, std::max(TimeMgr.available_time() / 8, 20)));
|
||||
if (Limits.use_time_management())
|
||||
Threads.set_timer(std::min(100, std::max(TimeMgr.available_time() / 16, TimerResolution)));
|
||||
else
|
||||
Threads.set_timer(100);
|
||||
|
||||
|
@ -513,7 +516,7 @@ namespace {
|
|||
bestMoveNeverChanged = false;
|
||||
|
||||
// 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
|
||||
|
||||
|
@ -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
|
||||
while ( bestValue < beta
|
||||
&& (move = mp.next_move()) != MOVE_NONE
|
||||
&& !thread.cutoff_occurred())
|
||||
&& !thread.cutoff_occurred()
|
||||
&& !Signals.stop)
|
||||
{
|
||||
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
|
||||
/// is used to print debug info and, more important, to detect when we are out of
|
||||
/// check_time() is called by the timer thread when the timer triggers. It is
|
||||
/// used to print debug info and, more important, to detect when we are out of
|
||||
/// available time and so stop the search.
|
||||
|
||||
void do_timer_event() {
|
||||
void check_time() {
|
||||
|
||||
static int lastInfoTime;
|
||||
int e = elapsed_time();
|
||||
|
@ -1979,10 +1983,10 @@ void do_timer_event() {
|
|||
&& !Signals.failedLowAtRoot
|
||||
&& e > TimeMgr.available_time();
|
||||
|
||||
bool noMoreTime = e > TimeMgr.maximum_time()
|
||||
bool noMoreTime = e > TimeMgr.maximum_time() - TimerResolution
|
||||
|| stillAtFirstMove;
|
||||
|
||||
if ( (Limits.useTimeManagement() && noMoreTime)
|
||||
if ( (Limits.use_time_management() && noMoreTime)
|
||||
|| (Limits.maxTime && e >= Limits.maxTime)
|
||||
/* missing nodes limit */ ) // FIXME
|
||||
Signals.stop = true;
|
||||
|
|
|
@ -55,7 +55,7 @@ struct Stack {
|
|||
struct 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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
// 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() {
|
||||
|
||||
|
@ -376,7 +376,7 @@ void Thread::timer_loop() {
|
|||
lock_grab(&sleepLock);
|
||||
timed_wait(&sleepCond, &sleepLock, maxPly ? maxPly : INT_MAX);
|
||||
lock_release(&sleepLock);
|
||||
do_timer_event();
|
||||
check_time();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ OptionsMap::OptionsMap() {
|
|||
o["OwnBook"] = UCIOption(true);
|
||||
o["MultiPV"] = UCIOption(1, 1, 500);
|
||||
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 Move Time"] = UCIOption(70, 0, 5000);
|
||||
o["Minimum Thinking Time"] = UCIOption(20, 0, 5000);
|
||||
|
|
Loading…
Add table
Reference in a new issue