Time Management after Ponderhit

Discussion of chess software programming and technical issues.

Moderator: Ras

gflohr
Posts: 61
Joined: Fri Jul 23, 2021 5:24 pm
Location: Elin Pelin
Full name: Guido Flohr

Time Management after Ponderhit

Post by gflohr »

I am implementing pondering in my engine. When it receives a "go ponder", the time control is set to infinite, but I still calculates the allocated time. Currently, I only perform that calculation at the start of the search, not after each iteration.

When a "ponderhit" is received, the search tree goes from ponder into normal mode, and the start time is reset to the current time.

In this setup, when the engine receives the "ponderhit" after n seconds, it will effectively search the position n seconds longer than the time allocation considered appropriate, and that doesn't look right to me because it is actually arbitrary.

Doing a "fair" distribution of the won extra time over the number of expected moves to go, depending on the ponder hit ratio of the game so far, is not feasible because UCI is stateless.

What is the best way to solve this?
User avatar
Volker Annuss
Posts: 181
Joined: Mon Sep 03, 2007 9:15 am

Re: Time Management after Ponderhit

Post by Volker Annuss »

Time Management with pondering is difficult. Imagine a match where both engines have ponderhits for a long sequence of moves. One of these engines might use much time while the other is calculating on the opponents time.

I give more time to my engine when pondering. When I would normally stop searching in normal search, I continue searching in ponder mode, but after a ponderhit I stop searching immediately without trying to finish the current iteration.
gflohr
Posts: 61
Joined: Fri Jul 23, 2021 5:24 pm
Location: Elin Pelin
Full name: Guido Flohr

Re: Time Management after Ponderhit

Post by gflohr »

At the moment, I simply give one fourth of the time won on top of the allocated time. I only stop searching immediately, when the newly allocated time is used up.

But I consider ignoring that altogether, which automatically distributes the time won over the following moves, and unless it is the first ponderhit in the game, the current search already benefits from all previous ponderhits. And a ponderhit rather indicates that the current position is not worth searching deeper than the opposite.

I think my next step will be to reallocate time after each iteration and take the volatility of the evaluation into account. Once that is done, I will most probably try to ignore the ponderhit and instead trust the recalculation that I have done for the current search. This is pretty much what I do myself when playing.
User avatar
hgm
Posts: 28413
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Time Management after Ponderhit

Post by hgm »

gflohr wrote: Sun Nov 16, 2025 9:09 amDoing a "fair" distribution of the won extra time over the number of expected moves to go, depending on the ponder hit ratio of the game so far, is not feasible because UCI is stateless.

What is the best way to solve this?
That UCI is stateless does not mean your engine has to be stateless. It would be wise, for instance, to keep the content of the hash table from the previous search.

The logical solution is to deduct the n seconds spent on the search before 'ponderhit' from the allocated time. And move immediately when that is negative.

You could collect statistics from the average time per move saved on ponderhits since the last 'newgame', and assume that this is what future moves would also save. You could then augment the allocated time with this expected ponder gain. Even if you don't want to take the statistics, you could assume some general factor, e.g. that in a ponder-on game you would get to think 25% more than the clock times specified in the 'go' command.

There is a risk, though (which would also apply to ponder-off games, b.t.w.): if the opponent things unusually long, it is probably because he stumbled on some deep tactics that changed the score appreciable, and that it wanted to resolve resulting fail lows or highs before moving. It might not be optimal to stubbornly stick to your own time allocation. So perhaps you should allocate a time for the search that depends on how long the opponent has thought on the previous move. Perhaps not fully, because you already have the advantage of starting the search one ply later, but (say) as sqrt(time_he_used*my_nominal_thinking_time). So if he thinks twice as long as normal, you would think 41% longer than normal, avoiding to be grossly outsearched, but still pocketing some time gain. In the 'ponderhit' case this would mean you can allocate the total time you still want too continue to think only on reception of 'ponderhit'.
Aleks Peshkov
Posts: 954
Joined: Sun Nov 19, 2006 9:16 pm
Location: Russia
Full name: Aleks Peshkov

Re: Time Management after Ponderhit

Post by Aleks Peshkov »

You only need to keep one extra variable: bool isPonderSearch. In function you check for timeout during search process you should fast exit when isPonderSearch == true. On ponderhit command you just set isPonderSearch = false, that all. On next regular time check you will check for timeout as normal.

You may allocate more time when option Ponder true and may check for timeout immediatelly during ponderhit command, but it is optional fine tuning.