Moderator: Andres Valverde
Michael Sherwin wrote:The last public release of my program RomiChess (p3k) has been barraged by so many inexplicable losses that I have gone on a bug hunt to try to find out why.
Only the high 32 bits of the hash signiture was being stored in the hash record. This seemed enough as storing the full 64 bits made no difference in performance.
So as an experiment I just added another 32 bits that is just used as the key and am storing the full original 64 bit signature/key as just the signature.
Only 50 games have been played, However, this is the best result for those 50 games that I have ever had.
Now I am wondering, how many good ideas tested bad, because they stumbled into more games that had hash errors.
And I am wondering just how many bits are really enough. Or maybe my hash value generation, for only 64 bits, is not good.
Also, now that I am using 96 bits, can I just use the hash move with out verification that the move exist and that it is legal. This could mean a big increase in node rate. Especially if it is extended to the qsearch().
Michael Sherwin wrote:That is what I think/thought! I am still looking. Here bug bug bug bug bug!
Dann Corbit wrote:If you use the low K bits of your hash for the hash table address and you store the upper 32 bits in the hash table, then you are actually using 32+k bits of your hash value for verification. For example, if you have 4 million hash table entries then you have 24+32 = 56 bits (because the low 24 bits are totally redundant -> only a value with those 24 bits matching would have been stored in that slot). The odds of a hash collision are therefore one in 2^56=72,057,594,037,927,936
If you search 10 million NPS then you will have one collision every 7205759403.8 seconds = one collision every 83400 days = one every 228 years.
Teemu Pudas wrote:Dann Corbit wrote:If you use the low K bits of your hash for the hash table address and you store the upper 32 bits in the hash table, then you are actually using 32+k bits of your hash value for verification. For example, if you have 4 million hash table entries then you have 24+32 = 56 bits (because the low 24 bits are totally redundant -> only a value with those 24 bits matching would have been stored in that slot). The odds of a hash collision are therefore one in 2^56=72,057,594,037,927,936
If you search 10 million NPS then you will have one collision every 7205759403.8 seconds = one collision every 83400 days = one every 228 years.
Your math is faulty. If the table is full (when isn't it?) every probe is guaranteed to be a k-bit collision. Mind you, one in 4 billion is of course still pretty insignificant.
.
P.K. Mukhopadhyay wrote:probability of a 32+k bit collision is very small - one in 2^(32+k).
Teemu Pudas wrote:P.K. Mukhopadhyay wrote:probability of a 32+k bit collision is very small - one in 2^(32+k).
No, it isn't. It's one in 2^32: the k bits collide every time you probe. 2^(32+k) is the probability that two specific positions collide; why would anyone care which one of the 4 million hash entries is the one that gets a collision?
Teemu Pudas wrote:No, it isn't. It's one in 2^32: the k bits collide every time you probe. {One in} 2^(32+k) is the probability that two specific positions collide; why would anyone care which one of the 4 million hash entries is the one that gets a collision?
P.K. Mukhopadhyay wrote:How does the supposedly buggy version fare against the older stable version?
P.K.Mukhopadhyay
Ron Murawski wrote:Dann is 100% correct. But that presupposes that your Zobrist random numbers are good. I had problems similar to yours when I used 2 successive 32-bit pseudo-random numbers to make one 64-bit number. The collision rate was extremely high. My original PRNG used the linear congruential method, where it is a known fact that the low-order bits are not as random as the high-order bits. (Art of Computer Programming, Volume 2, 3rd Edition, Donald Knuth, Section 3.6, item vi, p185) If you read the pseudo-random literature you will find that joining 2 successive numbers together to make a single larger one is also a mathematically weak technique.
You are better off using a list of empirically-tested known-good numbers (like in Crafty) or using a 64-bit pseudo-random number generator that is *not* generated through the linear congruential method.
At the moment I'm using ISAAC-64: http://burtleburtle.net/bob/rand/isaacafa.html
You'll need to scroll down the page a bit to find the 64-bit version.
Ron
Michael Sherwin wrote:In RomiChess I generate the hash values randomly, bit by bit, one bit at a time with the built in rand() function. Any thoughts?
Teemu Pudas wrote:Michael Sherwin wrote:In RomiChess I generate the hash values randomly, bit by bit, one bit at a time with the built in rand() function. Any thoughts?
Use a better generator and don't generate them bit by bit!
If you're doing rand() & 1, your numbers are most likely busted, as many rand() implementations use the linear congruential method...
Michael Sherwin wrote:Ron Murawski wrote:Dann is 100% correct. But that presupposes that your Zobrist random numbers are good. I had problems similar to yours when I used 2 successive 32-bit pseudo-random numbers to make one 64-bit number. The collision rate was extremely high. My original PRNG used the linear congruential method, where it is a known fact that the low-order bits are not as random as the high-order bits. (Art of Computer Programming, Volume 2, 3rd Edition, Donald Knuth, Section 3.6, item vi, p185) If you read the pseudo-random literature you will find that joining 2 successive numbers together to make a single larger one is also a mathematically weak technique.
You are better off using a list of empirically-tested known-good numbers (like in Crafty) or using a 64-bit pseudo-random number generator that is *not* generated through the linear congruential method.
At the moment I'm using ISAAC-64: http://burtleburtle.net/bob/rand/isaacafa.html
You'll need to scroll down the page a bit to find the 64-bit version.
Ron
Hi Ron,
In RomiChess I generate the hash values randomly, bit by bit, one bit at a time with the built in rand() function. Any thoughts?
Ron Murawski wrote: There's another school of thought that wants to measure Hamming distances between the numbers. The larger the distances, the better the 'Hamming' guys like the numbers. Both methods seem to work. The actual method is to find the two numbers in your Zobrist number table with the smallest Hamming distance. This is the value you want to maximize.
Ron
P.K. Mukhopadhyay wrote:Ron Murawski wrote: There's another school of thought that wants to measure Hamming distances between the numbers. The larger the distances, the better the 'Hamming' guys like the numbers. Both methods seem to work. The actual method is to find the two numbers in your Zobrist number table with the smallest Hamming distance. This is the value you want to maximize.
Ron
What Hamming distance/bits is considered satisfactory? If we consider three numbers A, /A and A^/A(i.e., all 1's) the minimum distance can be 50% of bits and yet they are related and useless for hashing.
Michael Sherwin wrote:Teemu Pudas wrote:Michael Sherwin wrote:In RomiChess I generate the hash values randomly, bit by bit, one bit at a time with the built in rand() function. Any thoughts?
Use a better generator and don't generate them bit by bit!
If you're doing rand() & 1, your numbers are most likely busted, as many rand() implementations use the linear congruential method...
Thanks! I will make the change.
Return to Programming and Technical Discussions
Users browsing this forum: No registered users and 8 guests