Is there any special reason for not clearing the TT after a new game has started? If there's no such reason I'd suggest to do so, because hashing over multiple games may lead to seldom tiny errors.
// Step 5. Evaluate the position statically and
// update gain statistics of parent move.
isCheck = pos.is_check();
if (isCheck)
ss->eval = evalMargin = VALUE_NONE;
else if (tte)
{
assert(tte->static_value() != VALUE_NONE);
ss->eval = tte->static_value();
assert(ss->eval == evaluate(pos, evalMargin)); // assert added by me
....
The assert(ss->eval == evaluate(pos, evalMargin)) may fail because of asymetric king safety eval in case the TT get not cleared after a new game has started.
Ralph Stoesser wrote:Is there any special reason for not clearing the TT after a new game has started? If there's no such reason I'd suggest to do so, because hashing over multiple games may lead to seldom tiny errors.
// Step 5. Evaluate the position statically and
// update gain statistics of parent move.
isCheck = pos.is_check();
if (isCheck)
ss->eval = evalMargin = VALUE_NONE;
else if (tte)
{
assert(tte->static_value() != VALUE_NONE);
ss->eval = tte->static_value();
assert(ss->eval == evaluate(pos, evalMargin)); // assert added by me
....
The assert(ss->eval == evaluate(pos, evalMargin)) may fail because of asymetric king safety eval in case the TT get not cleared after a new game has started.
I prefer that they don't because it will divide the value of my EPD analysis by two.
I often take all the moves of a game as a sequence of EPD records. Then I analyze them one by one, in order.
Now, my rule for clearing the hash table is:
If you get a request to clear the hash table, then ignore it.
If you get a request to clear the hash table and then you are given a position which you have never seen before then go ahead and clear it.
"Please clear the hash" was a sneaky trick introduced by the ChessBase GUI some time ago when non-chessbase engines were inserted into the interface. Since it was discovered, I guess that they have removed this dirty pool tactic, but it is another reason to ignore it.
I think that it is a bad behaviour to ignore clearing hash table command.
Chess engines should do what people tell them and users may want to clear the hash table for their reasons(not only when the engine get a new position for example to compare performance between different engines in the same position).
The fact that chessbase GUI used it in the past in matches is no reason to ignore it and it is better to ignore the relevant GUI and not to use it.
Ralph Stoesser wrote:Is there any special reason for not clearing the TT after a new game has started?
Short answer: Because it is stronger in long matches.
Long answer: During last year we started a long match against Rybka 3 and we noted that SF started well but then, after several hundreds games the winning scores decreased. We observed this behaviour many times and so we stopped clearing the hash at each new game and suddendly the score didn't decrease anymore.
So lessons learned were:
1 ) Don't clearing the TT at each new games gives an edge on long matches.
2) Very possibly Rybka does not clear the TT too
BTW as you know SF supports changing parameters values on the fly during the same game. This makes your assert fail anyway because user can always tweak the weights during a match so that the same position gives a different evaluation score.
I do not understand how clearing the hash after the game can make the program weaker in long matches.
It does not seem to me logical(assuming that the program has no special learning file) because the program is supposed to forget the relevant information from positions that it played many hours ago even without clearing the hash and the hash is not relevant in consecutive games assuming that you usually start from clearly different book positions in consecutive games.
I also think that a good interface should care to clear the hash of engines by simply killing the process of stockfish and the process of the opponent after every game and restarting the processes(because unfortunately it seems that we cannot trust engines to do it by themselves espacially after Dann Corbit's suggestion).
Uri Blass wrote:I do not understand how clearing the hash after the game can make the program weaker in long matches.
It does not seem to me logical(assuming that the program has no special learning file) because the program is supposed to forget the relevant information from positions that it played many hours ago even without clearing the hash and the hash is not relevant in consecutive games assuming that you usually start from clearly different book positions in consecutive games.
I also think that a good interface should care to clear the hash of engines by simply killing the process of stockfish and the process of the opponent after every game and restarting the processes(because unfortunately it seems that we cannot trust engines to do it by themselves espacially after Dann Corbit's suggestion).
I think that a deep analysed position from a previous game can be reused in a later game and because is deeply analyzed is not so easily overwritten. I am not able to come up with a better explanation.
UCI "newgame" command does not imply that hash must be cleared, that's why there is also UCI "Clear hash" parameter that exsists just for that, to ask the engine to clear the TT, and SF, of course, upon receiving a "Clear Hash" will onor the command.
Ralph Stoesser wrote:Is there any special reason for not clearing the TT after a new game has started?
Short answer: Because it is stronger in long matches.
Long answer: During last year we started a long match against Rybka 3 and we noted that SF started well but then, after several hundreds games the winning scores decreased. We observed this behaviour many times and so we stopped clearing the hash at each new game and suddendly the score didn't decrease anymore.
So lessons learned were:
1 ) Don't clearing the TT at each new games gives an edge on long matches.
2) Very possibly Rybka does not clear the TT too
...
Ok, I see. Thank you.
Another tiny glitch. Below I copy ss->eval into the local variable eval.
// Step 5. Evaluate the position statically and
// update gain statistics of parent move.
isCheck = pos.is_check();
if (isCheck)
ss->eval = evalMargin = VALUE_NONE;
else if (tte)
{
assert(tte->static_value() != VALUE_NONE);
ss->eval = tte->static_value();
evalMargin = tte->static_value_margin();
refinedValue = refine_eval(tte, ss->eval, ply);
}
else
{
refinedValue = ss->eval = evaluate(pos, evalMargin);
TT.store(posKey, VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, MOVE_NONE, ss->eval, evalMargin);
}
Value eval = ss->eval; // added by me
...
And right on the function return of search(), the assert(eval == ss->eval) will also fail sometimes. Seems to happen only if I hash across multiple games.
...
// Update killers and history only for non capture moves that fails high
if ( bestValue >= beta
&& !pos.move_is_capture_or_promotion(move))
{
update_history(pos, move, depth, movesSearched, moveCount);
update_killers(move, ss);
}
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
assert(eval == ss->eval) // added by me
return bestValue;
}
1 ) Don't clearing the TT at each new games gives an edge on long matches.
That's a very surprising result.
How can the hash table at the end of the previous game (including only end game positions) possibly have any influence on a new game?
Especially in a long TC match the hash table will be completely refreshed at each move. After a single move in the new game there will be nothing left from the hash table entries from the previous game.
This very much reminds me of homeopathic medicine .
mcostalba wrote:Please feel free to repeat the test (we used 1'+0" TC) and take us to the wonderful world of real medicine
I don't like to do something without at least trying to understand why it might be beneficial.
Assuming that one plays all positions twice with inverted colors, it is clear that the second game might benefit slightly from the analysis of the first game if the TC is that short that an important part of the entire game tree can be held in the hash table.
But that is an immediate impact (every second game benefits from the previous game), and not the situation that you describe in the SF-Rybka3 match where "after several hundreds games" there would be some mysterious impact from not clearing the hash. It simply doesn't make sense.