Random value compute or table hard coded ?

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

zongli
Posts: 13
Joined: Sat May 12, 2012 9:45 pm

Re: Random value compute or table hard coded ?

Post by zongli »

diep wrote:
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.
that requires code special for white and for black.
I dislike that.

Personally i prefer generic code that works for both sides, wherever it is possible...
I agree, although it depends on your setup whether you need to duplicate code. But I don't handle castling rights this way, anyway...
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: Random value compute or table hard coded ?

Post by syzygy »

diep wrote:Just out of interest - why do you need 16 random numbers for castling?
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].

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.
diep
Posts: 1822
Joined: Thu Mar 09, 2006 11:54 pm
Location: The Netherlands

Re: Random value compute or table hard coded ?

Post by diep »

syzygy wrote:
diep wrote:Just out of interest - why do you need 16 random numbers for castling?
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].

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.
Yes Zong was really fast :)

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 :)
diep
Posts: 1822
Joined: Thu Mar 09, 2006 11:54 pm
Location: The Netherlands

Re: Random value compute or table hard coded ?

Post by diep »

zongli wrote:
diep wrote:
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.
that requires code special for white and for black.
I dislike that.

Personally i prefer generic code that works for both sides, wherever it is possible...
I agree, although it depends on your setup whether you need to duplicate code. But I don't handle castling rights this way, anyway...
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 so :)

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.
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: Random value compute or table hard coded ?

Post by syzygy »

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.
Yes, and those 16 numbers are really just 4 numbers.
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.
It's a nice branchless way of updating castling status:
- 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.
User avatar
hgm
Posts: 27790
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Random value compute or table hard coded ?

Post by hgm »

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.