I too have had success using rotated Zobrist keys. As an experiment (a long time ago!) I modified Crafty to use rotated keys and had no collisions in the small number of self-play games I tried.
Cheers,
Steffan
On Zobrist keys
Moderator: Ras
-
steffan
- Posts: 28
- Joined: Sun Mar 12, 2006 12:08 am
- Location: Midlands, England
-
Gerd Isenberg
- Posts: 2251
- Joined: Wed Mar 08, 2006 8:47 pm
- Location: Hattingen, Germany
Re: On Zobrist keys
Hi Steffan,steffan wrote:I too have had success using rotated Zobrist keys. As an experiment (a long time ago!) I modified Crafty to use rotated keys and had no collisions in the small number of self-play games I tried.
Cheers,
Steffan
I wonder whether random base keys or De Bruin sequences work better. Two instead of more than 100 cachelines for a very frequent access will likely relax L1 a bit. Whether this is worth the rotate instruction, which is bound on cl? Likely.
Code: Select all
U64 CACHEALIGN basekey[16]; // 2 cachelines instead of > 100
ror(basekey[piece], square); // or rolCode: Select all
U64 zobristkey[16][64];
zobristkey[piece][square]; Gerd
-
steffan
- Posts: 28
- Joined: Sun Mar 12, 2006 12:08 am
- Location: Midlands, England
Re: On Zobrist keys
I think the ideal keys have on average half their bits set, and all bits are mutually independent. Random keys satisfy both criteria, but de Bruijn keys fail the independence criterion : For example, all de Bruijn sequences have exactly half their bits set.Gerd Isenberg wrote:I wonder whether random base keys or De Bruin sequences work better.
Cheers,
Steffan
Last edited by steffan on Mon Jun 22, 2009 10:01 pm, edited 1 time in total.
-
Edmund
- Posts: 670
- Joined: Mon Dec 03, 2007 3:01 pm
- Location: Barcelona, Spain
Re: On Zobrist keys
or you go forGerd Isenberg wrote:Hi Steffan,steffan wrote:I too have had success using rotated Zobrist keys. As an experiment (a long time ago!) I modified Crafty to use rotated keys and had no collisions in the small number of self-play games I tried.
Cheers,
Steffan
I wonder whether random base keys or De Bruin sequences work better. Two instead of more than 100 cachelines for a very frequent access will likely relax L1 a bit. Whether this is worth the rotate instruction, which is bound on cl? Likely.instead ofCode: Select all
U64 CACHEALIGN basekey[16]; // 2 cachelines instead of > 100 ror(basekey[piece], square); // or rolCheers,Code: Select all
U64 zobristkey[16][64]; zobristkey[piece][square];
Gerd
Code: Select all
U8 zobristkey[16*64+7]
return *(U64 *) (zobristkey + piece*64 + square);
and no additional ror/rol instruction
-
Gerd Isenberg
- Posts: 2251
- Joined: Wed Mar 08, 2006 8:47 pm
- Location: Hattingen, Germany
Re: On Zobrist keys
Might be quite expensive on x86, specially if you cross cacheline boarders. May be with some SSE4 unaligned load instruction.Codeman wrote: or you go for1031 bytes = 16.11 cachelinesCode: Select all
U8 zobristkey[16*64+7] return *(U64 *) (zobristkey + piece*64 + square);
and no additional ror/rol instruction
-
Aleks Peshkov
- Posts: 994
- Joined: Sun Nov 19, 2006 9:16 pm
- Location: Russia
- Full name: Aleks Peshkov
Re: On Zobrist keys
Random keys have random dependence. Set of only 12 de Bruijn keys (instead of 768 pseudo-random) can be easier to test, as they are proved to be good enough for itself rotation.steffan wrote:I think the ideal keys have on average half their bits set, and all bits are mutually independent. Random keys satisfy both criteria, but de Bruijn keys fail the independence criterion : For example, all de Bruijn sequences have exactly half their bits set.Gerd Isenberg wrote:I wonder whether random base keys or De Bruin sequences work better.
-
wgarvin
- Posts: 838
- Joined: Thu Jul 05, 2007 5:03 pm
- Location: British Columbia, Canada
Re: On Zobrist keys
You could however, overlap 12 keys for each square at 2-byte intervals and fit them all within an aligned 32-byte block. That gives you a 2 KB table (32*64 bytes) that requires no rotate and never does a read that crosses cacheline boundaries. Its not as compact as the rotated keys, but its better than the usual 6 KB (12*8*64).Gerd Isenberg wrote:Might be quite expensive on x86, specially if you cross cacheline boarders. May be with some SSE4 unaligned load instruction.Codeman wrote: or you go for1031 bytes = 16.11 cachelinesCode: Select all
U8 zobristkey[16*64+7] return *(U64 *) (zobristkey + piece*64 + square);
and no additional ror/rol instruction
Can anyone can think of a way to use 1-byte intervals and make the table smaller without causing some accesses to cross a cache line boundary? I tried to figure out a way, but have come up with nothing so far.
-
Zach Wegner
- Posts: 1922
- Joined: Thu Mar 09, 2006 12:51 am
- Location: Earth
Re: On Zobrist keys
You can do it if you muck with the address a bit to get the unused pieces (12-15) to cluster at the top of a cache line:
...or more bit-twiddlingly:
Code: Select all
unsigned char data[64*16];
s1=square&3;
s2=square>>2;
hashkey = *(u64*)(data+s2*64+s1+piece*4);Code: Select all
unsigned char data[64*16];
hashkey = *(u64*)(data+(square&~3)*15+square+piece*4);-
hgm
- Posts: 28502
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: On Zobrist keys
I am used to 0x88 boards and 32-bit code, and there this is almost automatic. One cache line contains 4 board ranks, but the high addresses in each rank, from which a 4-byte load (or even an 8-byte load) could cross a cache-line boundary, are not used. For the other half-key I swap the use of the black and white tables.wgarvin wrote:Can anyone can think of a way to use 1-byte intervals and make the table smaller without causing some accesses to cross a cache line boundary? I tried to figure out a way, but have come up with nothing so far.