Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: A faster move generator than previously known

Author: José Carlos

Date: 05:35:56 08/08/03

Go up one level in this thread


On August 08, 2003 at 07:56:21, Vincent Diepeveen wrote:

>On August 08, 2003 at 07:46:17, José Carlos wrote:
>
>>On August 08, 2003 at 07:40:14, Vincent Diepeveen wrote:
>>
>>>On August 08, 2003 at 02:50:01, José Carlos wrote:
>>>
>>>>On August 07, 2003 at 23:48:51, Vincent Diepeveen wrote:
>>>>
>>>>
>>>>  I've tried something like that in the past. My move generator is faster that
>>>>this one. In my other program (with non rotated bitboards) the move generator
>>>>alone is slower, but I can calculate many things very cheap. If I try to do in
>>>>my 0x88 program all the stuff I do in my bitboard program, it gets twice slower
>>>>instantly.
>>>
>>>
>>>
>>>>  Feel free to say that this happens because I'm a very bad programmer, if you
>>>>feel better that way.
>>>
>>>Yes you are a very poor programmer unless you tested at a 486.
>>>
>>>You hardly have branch mispredictions with this move generator in case you
>>>didn't notice. So it kicks the hell out of anything you do in advance,
>>>because 2 branch mispredictions is already more expensive than generating
>>>1 move with this generator.
>>
>>  Thanks for the (expected) compliment.
>>  I have zero branch mispredictions in my current move generator.
>>
>>  José C.
>
>then you should really test this.
>
>bitboards branchless is a zillion penalties. just see what penalties and
>register stalls Gerd measured.

  No, it's my 0x88 move generator that is branchless.
  My bitboard move generator is not optimized for speed because I'm writing the
eval now in my spare time.
  In my case: BB movgen + full eval every ply + much heavier eval than the other
program + SEE used everywhere + threat detection routine every node + many more
things = half the nps of the 0x88 program (only leaf eval, no SEE, threat
detection by null-move, ...) and of course I can search much deeper with the
bitboard program inspite of 1/2 nps rate. BTW, the bitboard program is not
optimized for speed at all. The 0x88 program is, and very carefully I'd say.
  I tested an algorithm similar to yours, some time ago, in the 0x88 program,
but was slower than the one I have today.

  José C.


>>>>  José C.
>>>>
>>>>
>>>>
>>>>
>>>>>You guys can figure out the rest i bet seeing this code.
>>>>>
>>>>>All that bitboard idiocy always. This kicks the hell out of it.
>>>>>
>>>>>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.02 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.