I'm trying to write a function that swaps the nibbles of a bitboard two by two.
Just to clarify what that means:
- a nibble is 4 bits (half a byte)
- a bitboard is therefore 16 nibbles: b = N0,N1, ..., N14,N15
- function should return: f(b) = N1,N0, N3,N2, ..., N15,N14
Is there a smart way to perform that operation really fast ?
Thank you
nibble swapping
Moderator: Ras
-
lucasart
- Posts: 3243
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
nibble swapping
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
-
mar
- Posts: 2672
- Joined: Fri Nov 26, 2010 2:00 pm
- Location: Czech Republic
- Full name: Martin Sedlak
Re: nibble swapping
Maybe shift left and mask or shift right and mask?lucasart wrote:I'm trying to write a function that swaps the nibbles of a bitboard two by two.
Just to clarify what that means:
- a nibble is 4 bits (half a byte)
- a bitboard is therefore 16 nibbles: b = N0,N1, ..., N14,N15
- function should return: f(b) = N1,N0, N3,N2, ..., N15,N14
Is there a smart way to perform that operation really fast ?
Thank you
Like ((b << 4) & maskhi) | ((b>>4) & masklo)?
-
Evert
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: nibble swapping
That's almost certainly the only portable solution. Note that it can be done on an entire bitboard in one go, assuming the encoding is A1=0, B1=1,...,H8=63, using exactly that code (and using suitable bitmasks).mar wrote:Maybe shift left and mask or shift right and mask?
Like ((b << 4) & maskhi) | ((b>>4) & masklo)?
Should be fast enough.
-
lucasart
- Posts: 3243
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Re: nibble swapping
Thanks. Simple and portablemar wrote:Maybe shift left and mask or shift right and mask?lucasart wrote:I'm trying to write a function that swaps the nibbles of a bitboard two by two.
Just to clarify what that means:
- a nibble is 4 bits (half a byte)
- a bitboard is therefore 16 nibbles: b = N0,N1, ..., N14,N15
- function should return: f(b) = N1,N0, N3,N2, ..., N15,N14
Is there a smart way to perform that operation really fast ?
Thank you
Like ((b << 4) & maskhi) | ((b>>4) & masklo)?
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
-
Evert
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: nibble swapping
There may also be something relevant at http://chessprogramming.wikispaces.com/ ... Techniques
-
hgm
- Posts: 28452
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: nibble swapping
Indeed, that is also the method I use for diagonal mirroring of position indexes in the fairygen EGT generator. (Except that the groups of bits I want to swap are only 3-wide rank and file number there. So I use b<<3 & 07070707070 | b>>3 & 0707070707).mar wrote:Maybe shift left and mask or shift right and mask?
Like ((b << 4) & maskhi) | ((b>>4) & masklo)?
For non-8x8 square boards I had a hard time finding something similarly simple. In the end I chose for keeping two separate keys, one collecting all rank coordinates, the other all file coordinates, so that I can do mirroring in one dimension or the other by subtracting the index from a constant. The total index is then rankIndex*WIDTH + fileIndex or fileIndex*WIDTH + rankIndex, depending on the diagonal mirror class I need.
-
Don
- Posts: 5106
- Joined: Tue Apr 29, 2008 4:27 pm
Re: nibble swapping
You could try using a 64k table that does the swapping 16 bits at a time. I don't know how fast or slow it would be but it would be worth a quick test.lucasart wrote:I'm trying to write a function that swaps the nibbles of a bitboard two by two.
Just to clarify what that means:
- a nibble is 4 bits (half a byte)
- a bitboard is therefore 16 nibbles: b = N0,N1, ..., N14,N15
- function should return: f(b) = N1,N0, N3,N2, ..., N15,N14
Is there a smart way to perform that operation really fast ?
Thank you
My best guess is that the shift intensive expression will be faster because even with lookup tables you will have to do a fair amount of shifting as well as 4 memory accesses and additional cache pressure.
Capital punishment would be more effective as a preventive measure if it were administered prior to the crime.