Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: RankAttacks with x^(x-2)

Author: Gerd Isenberg

Date: 03:41:35 10/01/02

Go up one level in this thread


On October 01, 2002 at 04:16:16, Sune Fischer wrote:

>On October 01, 2002 at 03:58:50, Gerd Isenberg wrote:
>
>>On September 30, 2002 at 15:39:09, Sune Fischer wrote:
>>
>>>On September 30, 2002 at 14:34:48, Gerd Isenberg wrote:
>>>
>>>>Hi all,
>>>>
>>>>i recently thought about and played with the x^(x-2) idea, introduced to me by
>>>>"The Hyperbola Project" some time ago.
>>>
>>>Isn't this the old reversed bitboards trick?
>>>How can you use this to generate the upper attack board, it only works on the
>>>lower bits?
>>
>>oups, it was little late yesterday...
>>
>>My intention so far is to use this x^(x-2) trick only to replace one direction
>>fill in Kogge-Stone or dumb7fill. So it improves shlightly the
>>getRookAttacksMMX, but a few percents more the getQueenAttacksMMX, due to easier
>>register usage, where finally dumb7fill fills five directions simultaniously
>>(left, leftup, leftdown, rightup, rightdown). Up/Down is done with KoggeStone,
>>right by this x^(x-2) trick.
>
>But why only one direction?


Better than nothing. It works with a set of multiple rooks even on one rank. So
it simply replaces one fill direction with this four or five mmx-instructions
(to get occupied from empty_squares use pxor with -1).



>   It should work in 2 directions for both bishop and
>rook? I used it once, but like you write below it isn't a good approach.
>
>Here is the forward part which does 2 direction, sorry haven't got an assembler
>version ;)
>
>/*
>a is the attack board
>o is the occupied board
>y is a dummy
>s is square of rook (0-63)
>*/
>
>// forward attacks
>a=o^(o-Mask(s+1));      // rank attacks + some above the rank
>a&=Rank(RANK(s));       // mask out the right direction (clean up)
>
>y=o&File(s);            // raw file
>y^=(y-Mask(s+1));       // attacks (pretty messed up)
>y&=File(FILE(s));       // mask out the right direction (clean up)
>
>a|=y;                   // add rank and file attacks!
>

Aha, nice, but seems only to work with one singular pieces (at least for files
and diagonals)? But anyway, the o^(o-Mask(sq+1)) trick was new to me. I guess
that Mask(sq) gets the singular BitBoard of the passed square (1<<sq), so
therefore it's equal with the "o^(o-2*rooks)" on ranks, if rooks has only one
bit set on this rank. But thanks to the psubb-instruction there is no possible
wrap to neighboring ranks, and therefore no need to mask the rank.

May be it's worth to implement a polymorph set of getxxxxAttacks with int
parameter, to use the trick in all positive directions, but KoggeStone or
dumb7fill for the remaining negative.

>
>>I dont't like the reversed bitboard idea in the matter to work in parallel with
>>two incompatible reversed attack sets.
>
>yes that sucks
>
>>I even don't understand how "The Hyperbola Project" handles file- or diagonal
>>attacks without rotated bitboards, so that these rays fit into one byte with
>>consecutive bits on this ray.
>
>I haven't heard about that project.
>
It's a few year ago (99-00?) where a site came up with this reversed bitboard
idea. It was also object of discussion here this time. Try GOOGLE with
"Hyperbola Project MMX". You may find a cached version of the original "New
Technology" site.

Gerd

>-S.
>
>>Gerd
>>
>>>
>>>> It works fine with bit 0, and i thought
>>>>that shifting to file zero is required, before generationg the attacks.
>>>>But that seems not to be necessary. The generalized term for one rank is simply
>>>>
>>>>    Occupied ^ (Occupied - 2*RookMover)
>>>>
>>>>where RookMover is subset of Occupied.
>>>
>>>What is RookMover, how do you generate it?
>>>
>>>-S.
>>>
>>>>This term produces all rank attacks of all RookMover in positve direction
>>>>(increasing file index, here A=0,8...;B=1,9...).
>>>>
>>>>What a surprise (at least for me)!
>>>>
>>>>sample rank (consider the reversed bit order due to bit0 is A):
>>>>BitIndex     01234567
>>>>Occupied(O)  01011101
>>>>RookMover(R) 01001000
>>>> 2*R         00100100
>>>>-2*R         00111011
>>>>Occupied(O)  01011101
>>>>  (O-2R)     01101001
>>>>O^(O-2R)     00110100
>>>>
>>>>
>>>>With 64-bit mmx-registers this can be done simultaniously with all eight ranks:
>>>>
>>>>input:  mm1 = RookMover subset of Occupied
>>>>             (may be forced by "por mm6,mm1")
>>>>        mm6 = Occupied
>>>>output: mm0 = (right)RookAttacks
>>>>
>>>>  movq  mm0, mm6 ; Occupied
>>>>  psubb mm0, mm1 ; Occupied -   RookMover
>>>>  psubb mm0, mm1 ; Occupied - 2*RookMover
>>>>  pxor  mm0, mm6 ; Occupied ^ (Occupied - 2*RookMover)
>>>>
>>>>I tried it with up/down Kogge-Stone and leftDumb7Fill.
>>>>But only a few percent better performance (24secs instead of 26secs /10**9).
>>>>With pure dumb7fill, the performance win was even less. The seven unrolled
>>>>fill-iterations with four independent mmx-instructions are not so much slower
>>>>than with three for the remaining directions.
>>>>
>>>>Cheers,
>>>>Gerd



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.