Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: A faster move generator than previously known

Author: Vincent Diepeveen

Date: 05:31:38 08/08/03

Go up one level in this thread


On August 08, 2003 at 08:23:04, Sune Fischer wrote:

>On August 08, 2003 at 07:42:06, Vincent Diepeveen wrote:
>
>>On August 08, 2003 at 06:47:34, Sune Fischer wrote:
>>
>>You miss the point completely Sune.
>
>Do you have a point?
>
>>I can completely branchless (only with a loop which as you might know hardly
>>generates branch mispredictions) generate semi legal moves with this also using
>>less RAM using general code.
>
>When you run it 10 mill times in a tight loop I would not expect many brach
>mispridictions.
>Another reason why the test is flawed.

you show another time you know nothing from how processors branch prediction
works. There is a lot of different processors out there and it just doesn't work
like *that*.

If you generate for say 16 pieces like 16 bitboards and try to get bits out of
'em with that code in crafty that uses branches then you will realize probably
also that at non-itanium processors you will get branch mispredictions.

It doesn't take away that the real beauty of my generator is trivially not made
for 10 million times in a row stuff.

Small cache usage (depending whether you put it in 'chars' or in 'ints') in
combination with just loops in evaluation for each piece. No hard predictions to
make.

>>So that kicks the hell out of anything you got over there.
>
>I have things that kick the hell out of anything you can do, so what?
>
>Gotta look at the big picture Vince.
>
>-S
>
>>>On August 07, 2003 at 23:48:51, Vincent Diepeveen wrote:
>>>
>>>>You guys can figure out the rest i bet seeing this code.
>>>>
>>>>All that bitboard idiocy always. This kicks the hell out of it.
>>>
>>>I doubt it, I can with bitboards incrementally generate 59 Mn/s on my 2Gig, you
>>>claim 73 Mn/s on 2.1Gig, but that's not incrementally I bet.
>>>
>>>Also, you seem to be doing Pseudo move gen, with a capital P, do you also add
>>>moves where the king walks into a check?
>>>This would make your silly test faster so I assume you do.
>>>
>>>Of course now you'll have to waste time sorting the illegal moves, not to
>>>mention making and unmaking them.
>>>
>>>Try and sort the moves, feel free to do bubble sort or whatever, you'll end up
>>>in the 20 Mn/s range.
>>>
>>>Btw. if I or others cared about optimizing this routine as much as you do, we'd
>>>all be going 100+ Mn/s :)
>>>
>>>-S.
>>>
>>>>Vincent Diepeveen,
>>>>8 august 2003  5:53 AM
>>>>
>>>>#if MSVC
>>>>__inline
>>>>#endif
>>>>void GenMovesI(RecursionBlock *rb,int sq) {
>>>>  int SRsq,piece,u,xside,*s,*t,side,*v,*w;
>>>>
>>>>  side  = rb->side;
>>>>  xside = rb->xside;
>>>>  SRsq  = (sq<<6);
>>>>  piece = board[sq];
>>>>  if( piece == pawn ) {
>>>>    v = ipiecepos[side][sq];
>>>>    w = ipawndir[side][sq];
>>>>    u = *v++;
>>>>    if( row(u) != 0 && row(u) != 7 ) {
>>>>      if( color[u] == neutral) {
>>>>        rb->zetend->zet = (SRsq|u);
>>>>        rb->zetend++;
>>>>        if( (u=*v) != 128 && color[u] == neutral ) { /* indien u == sq dan false
>>>>*/
>>>>          rb->zetend->zet = (SRsq|u);
>>>>          rb->zetend++;
>>>>        }
>>>>      }
>>>>
>>>>      u = *w++;
>>>>      if( color[u] == xside ) {/* ppos bevat geen 100, maar sq. */
>>>>        rb->zetend->zet = (SRsq|u|move_captures);
>>>>        rb->zetend++;
>>>>      }
>>>>      if( (u=*w) != 128 && color[u] == xside ) {
>>>>        rb->zetend->zet = (SRsq|u|move_captures);
>>>>        rb->zetend++;
>>>>      }
>>>>    }
>>>>    else {
>>>>      if( color[u] == neutral) {
>>>>        rb->zetend->zet = (SRsq|u|move_pqueen);
>>>>        rb->zetend++;
>>>>        rb->zetend->zet = (SRsq|u|move_pknight);
>>>>        rb->zetend++;
>>>>        rb->zetend->zet = (SRsq|u|move_prook);
>>>>        rb->zetend++;
>>>>        rb->zetend->zet = (SRsq|u|move_pbishop);
>>>>        rb->zetend++;
>>>>      }
>>>>      u = *w++;
>>>>      if( color[u] == xside) {/* captures */
>>>>        rb->zetend->zet = (SRsq|u|move_captures|move_pqueen);
>>>>        rb->zetend++;
>>>>        rb->zetend->zet = (SRsq|u|move_captures|move_pknight);
>>>>        rb->zetend++;
>>>>        rb->zetend->zet = (SRsq|u|move_captures|move_prook);
>>>>        rb->zetend++;
>>>>        rb->zetend->zet = (SRsq|u|move_captures|move_pbishop);
>>>>        rb->zetend++;
>>>>      }
>>>>      if( (u=*w) != 128 && color[u] == xside) {
>>>>        rb->zetend->zet = (SRsq|u|move_captures|move_pqueen);
>>>>        rb->zetend++;
>>>>        rb->zetend->zet = (SRsq|u|move_captures|move_pknight);
>>>>        rb->zetend++;
>>>>        rb->zetend->zet = (SRsq|u|move_captures|move_prook);
>>>>        rb->zetend++;
>>>>        rb->zetend->zet = (SRsq|u|move_captures|move_pbishop);
>>>>        rb->zetend++;
>>>>      }
>>>>    }
>>>>  }
>>>>  else {
>>>>    t = cancapside[side];
>>>>    if( sweep[piece] ) {
>>>>      int *vh,*wh,uh;
>>>>      s  = andscan[0];
>>>>      vh = ipiecepos[piece][sq];
>>>>      wh = iskippos[sq];
>>>>      uh = *vh++;
>>>>      do {
>>>>        int p1=snelbord[uh],sh=wh[uh]; /* local variables is faster for GCC/MSVC
>>>>*/
>>>>        vh += (s[p1]&sh);
>>>>        if( color[uh] != side ) {
>>>>          rb->zetend->zet = (SRsq|uh|t[p1]);
>>>>          rb->zetend++;
>>>>        }
>>>>      } while( (uh=*vh++) != 128 );
>>>>
>>>>      /*vi = gentable[piece-3][sq];
>>>>      s  = doorscan[0];
>>>>      u  = vi[sq];
>>>>      do {
>>>>        if( color[u] != side ) {
>>>>          cappiece = snelbord[u];
>>>>          rb->zetend->zet = (SRsq|u|t[cappiece]);
>>>>          rb->zetend++;
>>>>          u = vi[(s[cappiece]|u)];
>>>>        }
>>>>        else {
>>>>          u = vi[(64|u)];
>>>>        }
>>>>      } while( u != 128 );*/
>>>>    }
>>>>    else {
>>>>      v = ipiecepos[piece][sq];
>>>>      u = *v++;
>>>>      do {
>>>>        if( color[u] != side ) {
>>>>          rb->zetend->zet = (SRsq|u|t[snelbord[u]]);
>>>>          rb->zetend++;
>>>>        }
>>>>      } while( (u=*v++) != 128 );
>>>>    }
>>>>  }
>>>>}
>>>>
>>>>void MoveListI(RecursionBlock *rb,struct Move *CFEP) {
>>>>/* Generate all semi-legal moves. Check is ignored.
>>>>*/
>>>>  int f,to,from,u,*psq,*pend,*w;
>>>>
>>>>  to = CFEP->zet&63;
>>>>  rb->zetend = rb->SemiLegals;
>>>>  if( board[to] == pawn ) { /* for enpassant */
>>>>    from = (CFEP->zet>>6)&63;
>>>>    if( to-from == 16 || from-to == 16 ) {
>>>>      f = (to+from)>>1;
>>>>      w = ipawndir[rb->xside][f];
>>>>      u = *w++;
>>>>      if( color[u] == rb->side && board[u] == pawn ) {
>>>>        rb->zetend->zet = ((u<<6)|f|move_captures|move_enpassant);
>>>>        rb->zetend++;
>>>>      }
>>>>      if( (u=*w) != 128 && color[u] == rb->side && board[u] == pawn ) {
>>>>        rb->zetend->zet = ((u<<6)|f|move_captures|move_enpassant);
>>>>        rb->zetend++;
>>>>      }
>>>>    }
>>>>  }
>>>>
>>>>  psq  = PieceList[rb->side];
>>>>  pend = PieceList[rb->side]+PieceMax[rb->side];
>>>>  if( !castld[rb->side] ) {
>>>>    u = *psq;
>>>>    if( castle(rb->side,u,u+2) ) {
>>>>      rb->zetend->zet = ((u<<6)|(u+2)|move_castles);
>>>>      rb->zetend++;
>>>>    }
>>>>    if( castle(rb->side,u,u-2) ) {
>>>>      rb->zetend->zet = ((u<<6)|(u-2)|move_castles);
>>>>      rb->zetend++;
>>>>    }
>>>>  }
>>>>
>>>>  #if BOUNDSCHECKING
>>>>  pend++;
>>>>  do {
>>>>    pend--;
>>>>    if( *pend != 64 )
>>>>      GenMovesI(rb,*pend);
>>>>  } while( pend > psq );
>>>>  #else
>>>>  do {
>>>>    if( *pend != 64 )
>>>>      GenMovesI(rb,*pend);
>>>>  } while( --pend >= psq );
>>>>  #endif
>>>>} /* End MoveList() */



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.