Rein,Rein Halbersma wrote:Without hashing, the numbers are in the same ball park as Aart's, but apparently my hash table -as did Murray's- has a big performance hit (>2x) compared to Aart's.
@Aart: can you tell us a bit about your hash table specs? How much memory, how many entries, which kind of data structure and replacement scheme?
@Murray, Aart: (assuming you have an incremental Zobrist hash) did you also turn off hash updating for the plain / bulk-counting perft() runs?
Glad to give some more details.
My move generator always does incremental Zobrist updates, even for all cases I reported that don't use transposition tables at all (I simply did not feel like removing this intricate code; I suspect it would not have helped a lot anyway).
My hash entries in the transposition table consist of a 64-bit perft count, a 97-bit full position and an 8-bit depth, padded up to 24 bytes total. And, yes, I am aware that this does not line up nicely with cache line sizes. But since I could not reduce the size of hash entries further to the next smaller power of two, and since I found more padding beyond a multiple of 4 rather wasteful, I preferred this compromise with more entries over avoiding cache line splits.
I use a very simple replace-always scheme for the transposition table. That is, I simply overwrite hash entries with the most recent computed perft computations, regardless of their depth. I tried a few other schemes, such as only overwriting hash entries with deeper perft results, but found that the simple replace-always scheme performed surprisingly well. I did not investigate this in much detail, though, and I am sure better schemes exist.
Aart