Skip to content

Commit

Permalink
Retire "Extra thinking before accepting draw PVs"
Browse files Browse the repository at this point in the history
This patch simplifies the time management code, removing the extra
thinking time for moves with draw PV and increasing thinking time
for all moves proportionally by around 4%.

Last time when the time management was carefully tuned was 1.5-2 years
ago. As new patches were getting added, time management was drifting out
of optimum. This happens because when search becomes more precise pv and
score are becoming more stable, there are less fail lows, best move is
picked earlier and there are less best move changes. All this factors are
entering in time management, and average time per move is decreasing with
more and more good patches. For individual patches such effect is small
(except some) and may be up or down, but when there are many of them,
effect is more substantial. The same way benchmark with more and more
patches is slowly drifting down on average.

So my understanding that back in October adding more think time for draw
PV showed positive Elo because time management was not well tuned, there
was more time available, and think_hard patch applied this additional time
to moves with draw PV, while just retuning back to optimum would recover Elo
anyway. It is possible that absence of contempt also helped, as SF9 is showing
less 0.0 scores than the October version.

Anyway, to me it seems that proper place to deal with draw PV is search, and
contempt sounds as much better solution. In time management there is little
additional elo, and if some code is not helping like removed here, it is better
to discard it. It is simpler to find genuine improvement if code is clean.

• Passed STC:
LLR: 2.95 (-2.94,2.94) [-3.00,1.00]
Total: 20487 W: 4558 L: 4434 D: 11495
http://tests.stockfishchess.org/tests/view/5a7706ec0ebc5902971a9854

• Passed LTC:
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 41960 W: 7145 L: 7058 D: 27757
http://tests.stockfishchess.org/tests/view/5a778c830ebc5902971a9895

• Passed an additional non-regression [-5..0] test at the time control
of 60sec for the game (sudden death) with disabled draw adjudication:
LLR: 2.95 (-2.94,2.94) [-5.00,0.00]
Total: 8438 W: 1675 L: 1586 D: 5177
http://tests.stockfishchess.org/tests/view/5a7c3d8d0ebc5902971a9ac0

• Passed an additional non-regression [-5..0] test at the time control
of 1sec+1sec per move with disabled draw adjudication:
LLR: 2.97 (-2.94,2.94) [-5.00,0.00]
Total: 27664 W: 5575 L: 5574 D: 16515
http://tests.stockfishchess.org/tests/view/5a7c3e820ebc5902971a9ac3

This is a functional change for the time management code.

Bench: 4983414
  • Loading branch information
Leonid Pechenik authored and snicolet committed Feb 9, 2018
1 parent 211ebc5 commit d71adc5
Showing 1 changed file with 3 additions and 28 deletions.
31 changes: 3 additions & 28 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ namespace {
void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus);
void update_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietsCnt, int bonus);
void update_capture_stats(const Position& pos, Move move, Move* captures, int captureCnt, int bonus);
bool pv_is_draw(Position& pos);

// perft() is our utility to verify move generation. All the leaf nodes up
// to the given depth are generated and counted, and the sum is returned.
Expand Down Expand Up @@ -435,24 +434,19 @@ void Thread::search() {
bestValue - mainThread->previousScore };
int improvingFactor = std::max(229, std::min(715, 357 + 119 * F[0] - 6 * F[1]));

Color us = rootPos.side_to_move();
bool thinkHard = bestValue == VALUE_DRAW
&& Limits.time[us] - Time.elapsed() > Limits.time[~us]
&& ::pv_is_draw(rootPos);

double unstablePvFactor = 1 + mainThread->bestMoveChanges + thinkHard;
double unstablePvFactor = 1 + mainThread->bestMoveChanges;

// if the bestMove is stable over several iterations, reduce time for this move,
// the longer the move has been stable, the more.
// Use part of the gained time from a previous stable move for the current move.
timeReduction = 1;
for (int i : {3, 4, 5})
if (lastBestMoveDepth * i < completedDepth && !thinkHard)
if (lastBestMoveDepth * i < completedDepth )
timeReduction *= 1.3;
unstablePvFactor *= std::pow(mainThread->previousTimeReduction, 0.51) / timeReduction;

if ( rootMoves.size() == 1
|| Time.elapsed() > Time.optimum() * unstablePvFactor * improvingFactor / 628)
|| Time.elapsed() > Time.optimum() * unstablePvFactor * improvingFactor / 605)
{
// If we are allowed to ponder do not stop the search now but
// keep pondering until the GUI sends "ponderhit" or "stop".
Expand Down Expand Up @@ -1430,25 +1424,6 @@ namespace {
}
}


// Is the PV leading to a draw position? Assumes all pv moves are legal
bool pv_is_draw(Position& pos) {

StateInfo st[MAX_PLY];
auto& pv = pos.this_thread()->rootMoves[0].pv;

for (size_t i = 0; i < pv.size(); ++i)
pos.do_move(pv[i], st[i]);

bool isDraw = pos.is_draw(pv.size());

for (size_t i = pv.size(); i > 0; --i)
pos.undo_move(pv[i-1]);

return isDraw;
}


// When playing with strength handicap, choose best move among a set of RootMoves
// using a statistical rule dependent on 'level'. Idea by Heinz van Saanen.

Expand Down

0 comments on commit d71adc5

Please sign in to comment.