Newbie time control

Discussion of chess software programming and technical issues.

Moderator: Ras

micron
Posts: 155
Joined: Mon Feb 15, 2010 9:33 am
Location: New Zealand

Newbie time control

Post by micron »

Until recently my engine's time control was primitive, inflexible and just sufficient to play without losing on time.

Code: Select all

searchTimeLimit = totalTime*95/100/movesToGo;
When searchTimeLimit was exceeded, the current iteration was forcibly terminated and its results discarded (the best move and score being taken from the last completed iteration). If I understand correctly, about one third of the calculating time was simply wasted.

My first venture in real time control follows two precepts.

"Don't start what you can't finish".
Iteration is now stopped gracefully if this limit is exceeded:

Code: Select all

iterationTimeLimit = totalTime*65/100/movesToGo;
"Finish what you start".
More time than previously is allocated to a running iteration:

Code: Select all

searchTimeLimit = totalTime*40/100;
so that completion is more likely than forcible termination.

These changes are worth about 70 Elo.

My questions are
[1] Is it possible to salvage anything from an aborted iteration, or is that invariably unsafe?
[2] How else can I squeeze a few more Elo from time control?

Robert P.
Dann Corbit
Posts: 12828
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: Newbie time control

Post by Dann Corbit »

micron wrote:Until recently my engine's time control was primitive, inflexible and just sufficient to play without losing on time.

Code: Select all

searchTimeLimit = totalTime*95/100/movesToGo;
When searchTimeLimit was exceeded, the current iteration was forcibly terminated and its results discarded (the best move and score being taken from the last completed iteration). If I understand correctly, about one third of the calculating time was simply wasted.

My first venture in real time control follows two precepts.

"Don't start what you can't finish".
Iteration is now stopped gracefully if this limit is exceeded:

Code: Select all

iterationTimeLimit = totalTime*65/100/movesToGo;
"Finish what you start".
More time than previously is allocated to a running iteration:

Code: Select all

searchTimeLimit = totalTime*40/100;
so that completion is more likely than forcible termination.

These changes are worth about 70 Elo.

My questions are
[1] Is it possible to salvage anything from an aborted iteration, or is that invariably unsafe?
[2] How else can I squeeze a few more Elo from time control?

Robert P.
Do you have rules for Fischer increments?

Do you keep track of the opponent's time trouble?

Do you have a rule for a massive fail low?

Do you have a rule for a massive fail high? (OK, this one is easy).
micron
Posts: 155
Joined: Mon Feb 15, 2010 9:33 am
Location: New Zealand

Re: Newbie time control

Post by micron »

Do you have rules for Fischer increments?
Only simple accounting:

Code: Select all

totalTime = moveTime + incr*(movesToGo - 1);
Is there some subtle time control opportunity I should be thinking about, when (incr != 0)?
Do you keep track of the opponent's time trouble?
Interesting suggestion. What would be an appropriate change in time control? Play faster so that he can't ponder so well?
Do you have a rule for a massive fail low?
That requires another time-limit, right? Desperation time allocated in the hope of redoing the iteration with decreased alpha. I have tried along those lines, but cannot get any Elo advantage. On the first fail low I reduce alpha by a small amount and re-search; if that fails too, alpha is set to -INFINITY to get a definitive result. I'll try activating desperationTime only on the second fail-low, and see if it works any better.
Do you have a rule for a massive fail high? (OK, this one is easy).
No. There is no 'massive' fail high. I raise beta immediately on any fail-high move and re-search it at once. If I understand aright, there would be little role for time control here. But hey, what do I know? I'm a time control newbie.

Robert P.
Dann Corbit
Posts: 12828
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: Newbie time control

Post by Dann Corbit »

micron wrote:
Do you have rules for Fischer increments?
Only simple accounting:

Code: Select all

totalTime = moveTime + incr*(movesToGo - 1);
Is there some subtle time control opportunity I should be thinking about, when (incr != 0)?
Do you keep track of the opponent's time trouble?
Interesting suggestion. What would be an appropriate change in time control? Play faster so that he can't ponder so well?
Do you have a rule for a massive fail low?
That requires another time-limit, right? Desperation time allocated in the hope of redoing the iteration with decreased alpha. I have tried along those lines, but cannot get any Elo advantage. On the first fail low I reduce alpha by a small amount and re-search; if that fails too, alpha is set to -INFINITY to get a definitive result. I'll try activating desperationTime only on the second fail-low, and see if it works any better.
Do you have a rule for a massive fail high? (OK, this one is easy).
No. There is no 'massive' fail high. I raise beta immediately on any fail-high move and re-search it at once. If I understand aright, there would be little role for time control here. But hey, what do I know? I'm a time control newbie.

Robert P.
Most people have different rules for time control when the Fischer increment is non-zero. There are also subtle adjustments for tournament conditions when time is allowed for operator actions.

When the opponent has time trouble it can make sense to move faster if you have an advantage and the engines are pondering. It can also make sense to slow down for a while if you have a big surplus and the engines are not pondering.

On fail lows, I have seen up to 4 windows used -- the initial window, a + one pawn window, a plus 3 pawn window and an infintite window is one combination that I have seen.

One tactic to use if you get a big fail low is to increase the lower bound to + 1/2 pawn above your current position. The notion is to try to recover from a bad position by discovering a deep tactical shot. It is how the original Rybka Windfinder program worked.

I would suggest looking over how some open source programs do time control. Think about why they might make the choices that they have made. When you find some ideas that you like, try experimenting by playing large numbers of games using different rule sets with a window above and below to zoom in on what works well for you. Different time control startegies work differently on different programs. So the best thing to do is consider a bunch of ideas and experiment with them.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Newbie time control

Post by bob »

micron wrote:Until recently my engine's time control was primitive, inflexible and just sufficient to play without losing on time.

Code: Select all

searchTimeLimit = totalTime*95/100/movesToGo;
When searchTimeLimit was exceeded, the current iteration was forcibly terminated and its results discarded (the best move and score being taken from the last completed iteration). If I understand correctly, about one third of the calculating time was simply wasted.

My first venture in real time control follows two precepts.

"Don't start what you can't finish".
Iteration is now stopped gracefully if this limit is exceeded:

Code: Select all

iterationTimeLimit = totalTime*65/100/movesToGo;
"Finish what you start".
More time than previously is allocated to a running iteration:

Code: Select all

searchTimeLimit = totalTime*40/100;
so that completion is more likely than forcible termination.

These changes are worth about 70 Elo.

My questions are
[1] Is it possible to salvage anything from an aborted iteration, or is that invariably unsafe?
[2] How else can I squeeze a few more Elo from time control?

Robert P.
If you have a best move that is backed up to ply 1 before time runs out, you can always trust that. But once you start to unwind the search deeper in the tree, nothing you have done so far must get back to the root since the various searches are incomplete and the values are not correct yet.

One easy to do idea, if you start an iteration, and you search the first couple of moves and then run out of time, make sure you complete the _current_ move before you back out. Why? You will occasionally change your mind on the best move, and when you do, it takes a lot of time. If you are not going to change your mind, each root move is searched almost instantly. So finish the current one. You might waste a second here and there, but on occasion, you will use an extra minute or two and also find a better move to play.

BTW I do not like the idea of not starting an iteration just because you don't think you can finish it...
outAtime
Posts: 226
Joined: Sun Mar 08, 2009 3:08 pm
Location: Canada

Re: Newbie time control

Post by outAtime »

You could try something like this for adding time when the root score drops.
think() is the iterative deepening process which calls root_search()

so in think():

Code: Select all

last_root_score = cur_score;
and then in root_search()

Code: Select all

if root_score > alpha.....

alpha = root_score;
best_move = moves[i];
cur_score = alpha;

/* see if our root score has dropped a lot: */
			if ((cur_score + 90) < last_root_score) {
				bad_root_score = TRUE;
			}
so the external int bad_root_score is set and then in the main search() is used by:

Code: Select all

 if (bad_root_score) {   	               
	if (time_left > (5*time_for_move)) {       
	  time_for_move *= 2;                       
	}   
maybe this will give you some ideas. another flag could be used for moves which raise the score by a large amount etc..
outAtime
bhlangonijr
Posts: 482
Joined: Thu Oct 16, 2008 4:23 am
Location: Milky Way

Re: Newbie time control

Post by bhlangonijr »

Hello.

I did the function shown bellow a long time ago in RedQueen and it was worth some Elo - I don't remember how much. I had to fiddle around with the function to get what I was expecting and actually I never tested it throughly, so maybe it is buggy.

The idea is try to predict the new iteration time based on the weighted average growth ratio of the last three iterations. I noticed that it has a exponential growth proportional to the searching depth and number of root moves. After predicting the new iteration time, I don't search the next iteration if the predicted time is greater than the time remaining. This way I prevent the time management routines giving more and more time to unfinished iterations.

Obs.: It should be done only after at least the three first iterations within the iterative deepening function. :)

Code: Select all

inline long SimplePVSearch::predictTimeUse(const long iterationTime[maxSearchPly], const long totalTime, const int depth) {
	double ratio1 = double(iterationTime[depth-1])/double(totalTime);
	double ratio2 = double(iterationTime[depth-2])/double(totalTime);
	double ratio3 = double(iterationTime[depth-3])/double(totalTime);
	double newRatio = ratio1*exp((ratio2/ratio1)*0.7 + (ratio3/ratio2)*0.3);
	double newTime = double(iterationTime[depth-1])*exp(newRatio);
	return long(newTime);
}
Regards,
User avatar
Don
Posts: 5106
Joined: Tue Apr 29, 2008 4:27 pm

Re: Newbie time control

Post by Don »

micron wrote:Until recently my engine's time control was primitive, inflexible and just sufficient to play without losing on time.

Code: Select all

searchTimeLimit = totalTime*95/100/movesToGo;
When searchTimeLimit was exceeded, the current iteration was forcibly terminated and its results discarded (the best move and score being taken from the last completed iteration). If I understand correctly, about one third of the calculating time was simply wasted.

My first venture in real time control follows two precepts.

"Don't start what you can't finish".
Iteration is now stopped gracefully if this limit is exceeded:

Code: Select all

iterationTimeLimit = totalTime*65/100/movesToGo;
"Finish what you start".
More time than previously is allocated to a running iteration:

Code: Select all

searchTimeLimit = totalTime*40/100;
so that completion is more likely than forcible termination.

These changes are worth about 70 Elo.

My questions are
[1] Is it possible to salvage anything from an aborted iteration, or is that invariably unsafe?
[2] How else can I squeeze a few more Elo from time control?

Robert P.
It seems to be an important concept to extend the time control if the program has changed it's mind on the previous iteration. I tried to prove that was not important as I don't like wasting time on any given move, but in every experiment I have tried I have not been about to remove that rule. It works.

My program also tries not to start an iteration that it might not complete, but you cannot go too wild with this. I think my numbers are close to yours but if the program has changed moves we are much more likely to start the next iteration. We are also pretty liberal about finishing an iteration one we have started.

I would be careful about trusting your intuition on any of this, it really has to be tested pretty thoroughly. We tried several ideas we thought were natural and intuitive but they failed to produce an improvement and in fact many things hurt the program.