Fun with De Bruijn
Moderators: hgm, Harvey Williamson, bob
Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
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).
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.
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: 736
- Joined: Sun Aug 03, 2014 2:48 am
- Location: London, UK
- Contact:
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).
Author of Giraffe, an engine based on deep reinforcement learning. https://bitbucket.org/waterreaction/giraffe/overview
-
Dann Corbit
- Posts: 8662
- Joined: Wed Mar 08, 2006 7:57 pm
- Location: Redmond, WA USA
- Contact:
Re: Fun with De Bruijn
Csharp has both 64 bit integers and shift operations.
-
matthewlai
- Posts: 736
- Joined: Sun Aug 03, 2014 2:48 am
- Location: London, UK
- Contact:
Re: Fun with De Bruijn
But no bitscan?Dann Corbit wrote:Csharp has both 64 bit integers and shift operations.
Author of Giraffe, an engine based on deep reinforcement learning. https://bitbucket.org/waterreaction/giraffe/overview
-
Dann Corbit
- Posts: 8662
- Joined: Wed Mar 08, 2006 7:57 pm
- Location: Redmond, WA USA
- Contact:
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: 70
- Joined: Thu Jan 12, 2012 11:39 pm
- Location: London, England
- Contact:
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];
}Not a man to mince words. People, yes. But not words.
- hgm
- Posts: 22274
- Joined: Fri Mar 10, 2006 9:06 am
- Location: Amsterdam
- Full name: H G Muller
- Contact:
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: 641
- Joined: Wed Jun 18, 2014 12:30 pm
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).
'I would only believe in a god who could dance.' - Friedrich Nietzsche

