Fun with De Bruijn
Moderator: Ras
-
Henk
- Posts: 7251
- Joined: Mon May 27, 2013 10:31 am
Fun with De Bruijn
I wanted to convert a bitboard position into a square position. So I decided to use a de Bruijn sequence to calculate row and colnr but it did not work. Finally it is working but what is wrong with using a simple Math.Log(bb, 2).
-
bob
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: Fun with De Bruijn
Do NOT get Gerd started on this again.Henk wrote:I wanted to convert a bitboard position into a square position. So I decided to use a de Bruijn sequence to calculate row and colnr but it did not work. Finally it is working but what is wrong with using a simple Math.Log(bb, 2).
your head will explode.
-
stegemma
- Posts: 859
- Joined: Mon Aug 10, 2009 10:05 pm
- Location: Italy
- Full name: Stefano Gemma
Re: Fun with De Bruijn
There's nothing bad in any method but I think that you should try various ones and see what is the fastest in your program. For my engine, BitScaForward64 is the fastest but the second choice is simply getting row/columns and add together with row*8+col. Using DeBruijn seems slower, in my test.
Author of Drago, Raffaela, Freccia, Satana, Sabrina.
http://www.linformatica.com
http://www.linformatica.com
-
matthewlai
- Posts: 793
- Joined: Sun Aug 03, 2014 4:48 am
- Location: London, UK
Re: Fun with De Bruijn
It would be extremely slow. Both bb and 2 have to be converted to float first, have the log done (which is slow), and then converted back to int.Henk wrote:I wanted to convert a bitboard position into a square position. So I decided to use a de Bruijn sequence to calculate row and colnr but it did not work. Finally it is working but what is wrong with using a simple Math.Log(bb, 2).
Pre-mature optimizations is bad... but don't pessimize prematurely, too. This is done a lot in eval and/or move generation (both are on the critical path), so attention does need to be paid to performance.
If the C# standard library doesn't provide a bitscan method which uses the CPU's bitscan instruction when available, there's not much you can do. That's the price you pay for using a managed language. That's why most people use C/C++ for performance-critical stuff (like chess engines).
Disclosure: I work for DeepMind on the AlphaZero project, but everything I say here is personal opinion and does not reflect the views of DeepMind / Alphabet.
-
Dann Corbit
- Posts: 12828
- Joined: Wed Mar 08, 2006 8:57 pm
- Location: Redmond, WA USA
Re: Fun with De Bruijn
Csharp has both 64 bit integers and shift operations.
-
matthewlai
- Posts: 793
- Joined: Sun Aug 03, 2014 4:48 am
- Location: London, UK
Re: Fun with De Bruijn
But no bitscan?Dann Corbit wrote:Csharp has both 64 bit integers and shift operations.
Disclosure: I work for DeepMind on the AlphaZero project, but everything I say here is personal opinion and does not reflect the views of DeepMind / Alphabet.
-
Dann Corbit
- Posts: 12828
- Joined: Wed Mar 08, 2006 8:57 pm
- Location: Redmond, WA USA
Re: Fun with De Bruijn
No bitscan.
C# Alfil (for instance) uses DeBruijn and tables.
C# Alfil (for instance) uses DeBruijn and tables.
-
RoadWarrior
- Posts: 73
- Joined: Fri Jan 13, 2012 12:39 am
- Location: London, England
- Full name: Mark Pearce
Re: Fun with De Bruijn
My C# BitScanForward code:
Code: Select all
private const UInt64 DEBRUIJN64 = 0x03f79d71b4cb0a89;
private static readonly Byte[] INDEX64 =
{
0, 47, 1, 56, 48, 27, 2, 60,
57, 49, 41, 37, 28, 16, 3, 61,
54, 58, 35, 52, 50, 42, 21, 44,
38, 32, 29, 23, 17, 11, 4, 62,
46, 55, 26, 59, 40, 36, 15, 53,
34, 51, 20, 43, 31, 22, 10, 45,
25, 39, 14, 33, 19, 30, 9, 24,
13, 18, 8, 12, 7, 6, 5, 63
};
internal static Byte BitScanForward(UInt64 bitmap)
{
Debug.Assert(bitmap != 0);
return INDEX64[((bitmap ^ (bitmap - 1)) * DEBRUIJN64) >> 58];
}There are two types of people in the world: Avoid them both.
-
hgm
- Posts: 28461
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Fun with De Bruijn
Yes, that is a pretty efficient method. And its advantage over hardware bitscans is that you can fill the lookup table with arbitrary numbers, so that you can also tabulate other things than just the bit number, which otherwise would require a second lookup indexed by square number, or a calculation. For instance, if you use 0x88-style square numbering, rather than just 0-63.
-
vittyvirus
- Posts: 646
- Joined: Wed Jun 18, 2014 2:30 pm
- Full name: Fahad Syed
Re: Fun with De Bruijn
Wow! This is the fastest way I've heard of. I wonder why people are wasting their time with magic (debruijn) hashing based methods. They involve a lot of instructions compared to this: Math.Log(bb, 2)! Just one instruction!!! I haven't done benchmarks yet, but I predict it is 13.64 times faster than with debruijn hashing. Also, Math.Log(bb, 2) gives you the advantage of using 2, which is quite hardware friendly, and this method can even take advantages of floating point hardware intrinsics, and thus making it even faster. I don't think your idea is original, but still I'd appreciate you for making us know tjis revolutionary idea.Henk wrote:I wanted to convert a bitboard position into a square position. So I decided to use a de Bruijn sequence to calculate row and colnr but it did not work. Finally it is working but what is wrong with using a simple Math.Log(bb, 2).