I agree, although it depends on your setup whether you need to duplicate code. But I don't handle castling rights this way, anyway...diep wrote:that requires code special for white and for black.zongli wrote:Well, if castling rights are stored as 4 bits, you can just XOR it out, update it, and XOR it back in. Hence 16 random numbers.
I dislike that.
Personally i prefer generic code that works for both sides, wherever it is possible...
Random value compute or table hard coded ?
Moderators: hgm, Rebel, chrisw
-
- Posts: 13
- Joined: Sat May 12, 2012 9:45 pm
Re: Random value compute or table hard coded ?
-
- Posts: 5569
- Joined: Tue Feb 28, 2012 11:56 pm
Re: Random value compute or table hard coded ?
They are 16 XOR'd combinations of 4 random numbers. The trick is to keep track of castling status in 4 bits, then update the hash key by XOR'ing with RandomCastle[old_status ^ new_status].diep wrote:Just out of interest - why do you need 16 random numbers for castling?
So the RandomCastle[] array has to be initialised with care. Just putting in 16 random numbers will not work (correctly).
Another trick is to update castling status by AND'ing with CastleMask[from_square] & CastleMask[to_square].
edit: oops, it seems this was already answered. You don't need special code for white and black, though.
-
- Posts: 1822
- Joined: Thu Mar 09, 2006 11:54 pm
- Location: The Netherlands
Re: Random value compute or table hard coded ?
Yes Zong was really fastsyzygy wrote:They are 16 XOR'd combinations of 4 random numbers. The trick is to keep track of castling status in 4 bits, then update the hash key by XOR'ing with RandomCastle[old_status ^ new_status].diep wrote:Just out of interest - why do you need 16 random numbers for castling?
So the RandomCastle[] array has to be initialised with care. Just putting in 16 random numbers will not work (correctly).
Another trick is to update castling status by AND'ing with CastleMask[from_square] & CastleMask[to_square].
edit: oops, it seems this was already answered. You don't need special code for white and black, though.
Note that you just need to store the castling rights for the 2 rooks, not from-to nor for the king.
So you need just 4 numbers in total in theory.
Probably they managed to save out another cycle with this and every cycle is 1 if you're at that massive speed of around a 20 million nps at a single socket.
In diep i lucky don't suffer from that disease, though saving out cycles is part of business
-
- Posts: 1822
- Joined: Thu Mar 09, 2006 11:54 pm
- Location: The Netherlands
Re: Random value compute or table hard coded ?
Reminds me that last time i did do systematic effort getting Diep more code efficient suited onto the processor at that time, that was around 1998 or sozongli wrote:I agree, although it depends on your setup whether you need to duplicate code. But I don't handle castling rights this way, anyway...diep wrote:that requires code special for white and for black.zongli wrote:Well, if castling rights are stored as 4 bits, you can just XOR it out, update it, and XOR it back in. Hence 16 random numbers.
I dislike that.
Personally i prefer generic code that works for both sides, wherever it is possible...
It's duck slow right now.
It's L1i missrate is around 1.34% going up to 1.6%, so removing unecessary instructions sure is going to speed it up a lot.
A way to do that is generic code usually.
Not with all patterns in evaluation function this is easy to do; just directly checking it for white and for black is a lot easier to program. Sometimes i still do big effort then to convert it to generic code, after i'm sure the new pattern works - but it's not easy.
-
- Posts: 5569
- Joined: Tue Feb 28, 2012 11:56 pm
Re: Random value compute or table hard coded ?
Yes, and those 16 numbers are really just 4 numbers.diep wrote:Note that you just need to store the castling rights for the 2 rooks, not from-to nor for the king.
So you need just 4 numbers in total in theory.
It's a nice branchless way of updating castling status:Probably they managed to save out another cycle with this and every cycle is 1 if you're at that massive speed of around a 20 million nps at a single socket.
- new_status = old_status & castlemask[from] & castlemask[to];
- hashkey ^= castlerandom[new_status ^ old_status];
where castlemask[sq] is 15 for all squares except A1, E1, H1, A8, E8, H8.
-
- Posts: 27869
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Random value compute or table hard coded ?
Most of my engines also use 4 flags for castling, (KQkq), packed into one byte. I update them from the piece list rather than the board:
rights &= spoiler[piece] & spoiler[victim];
Rather than using it as an index in a table, I just multiply it by some magic constant, like 77607289763*rights to make a key from it.
I also don't update the castling part of the key incrementally. Just XOR (or add) it to the board key whenever I do the hash probe. It would have to be done once per node anyway. Same for the stm and e.p. key. Only for the board key incremental update brings you any savings. The others change (or could change) every turn.
Actually updating for the stm key can be eliminated by assigning the stm key to all empty squares. (Actually by XORing the stm key to every element of the piece-square key table, but you would not notice the difference for the non-zero elements.) You then only have to do
boardKey ^= keys[piece][from] ^ keys[piece][to] ^ keys[victim][to];
If victim == EMPTY this would then toggle the stm key for free.
rights &= spoiler[piece] & spoiler[victim];
Rather than using it as an index in a table, I just multiply it by some magic constant, like 77607289763*rights to make a key from it.
I also don't update the castling part of the key incrementally. Just XOR (or add) it to the board key whenever I do the hash probe. It would have to be done once per node anyway. Same for the stm and e.p. key. Only for the board key incremental update brings you any savings. The others change (or could change) every turn.
Actually updating for the stm key can be eliminated by assigning the stm key to all empty squares. (Actually by XORing the stm key to every element of the piece-square key table, but you would not notice the difference for the non-zero elements.) You then only have to do
boardKey ^= keys[piece][from] ^ keys[piece][to] ^ keys[victim][to];
If victim == EMPTY this would then toggle the stm key for free.