JoAnnP38 wrote: ↑Thu Aug 24, 2023 9:09 am
syzygy wrote: ↑Wed Aug 23, 2023 2:02 am
JoAnnP38 wrote: ↑Mon Aug 21, 2023 11:18 am
I do not check the TT move for legality. If it was legal going in, I expect that 99.99999%+ of the time it will be legal coming out. I do, however, store the full Zobrist key of the position in the hash table item and make sure it matches the current position before accepting that as a TT match. Someday, this may prove to be a poor decision, but that day is not today.
If your hash key is 64 bits and you have a hash table with 2^32 positions, then you only have 32 unique bits left. If the hash table is full, you will get 1 collision every 2^32 TT probes. If you probe in the Qsearch, this can lead to a crash every hour or so.
I think your calculations are probably off in some manner.
They are off only by the ratio of real hits. I don't know what is a normal ratio of real hits, but it won't be more than 50%
Also I am not taking into account buckets, but they won't totally change the equation (probably make it worse rather than better).
Moreover, I suspect that two different positions that have the same Zobrist key don't look much alike and thus the probability of them appearing in the TT at the same time are essentially nil especially if that TT supports aging.
A good aging strategy can help improve the hit ratio, but it won't do more than that.
Zobrist keys do a relatively good job at being uniformly randomly distributed. You can't expect them to do better than that.
Of course, that is only a hunch and has no mathematical backing.
And I have backed up my claim mathematically.
If you have a 64-bit key and 2^32 hash entries, you have 32 bits left to disambiguate. If your hash table is already nearly filled (which will take some small multiple of 2^32 nodes), then any further lookup will find a TT position whose hashkey necessarily agrees on the 32 bits that you use to index into the hash table. The other 32 bits will agree (1) if there is a valid hit (which is what you want) and (2) in about 1 in every 2^32 lookups which are not valid hits. In case (2) the stored tt move MIGHT be sufficiently valid for your engine to survive, but chances are quite good that your engine will crash.
So about every 2^33 nodes in which you do a TT lookup and play the TT move, your engine will crash (2^33 takes into account the real hits and the times that your engine is lucky and survives).
If you do 10 million nodes per second, that gives your engine 859s or about 15 minutes. Starting from an empty (and zero'd) hashtable, you can add maybe 30 minutes. But in real games you can assume your hashtable is filled (unless you clear it between moves, which is not recommended).
Every time you halve the size of the hashtable, you add a bit for disambiguation, so the 15 minutes will double (and the time needed to fill the hashtable will halve).
With a generous 16 bytes per TT entry, 2^32 entries means 64 GB of hash, which nowadays is very realistic.
Given that I've not run into this problem once that I'm aware of makes me doubt the importance of spending the CPU time it would take to validate the move for legality. On top of that, Pedantic also supports the Polyglot opening book format and it also indexes moves by Zobrist hash. I don't check those for legality either and have not had a problem their either. One of these days I might and then I'll probably cobble together some validation code, but not today.
You are not testing with 64 GB of hash.