Micro-optimize castleRights update
authorMarco Costalba <mcostalba@gmail.com>
Sat, 18 Feb 2012 20:30:33 +0000 (21:30 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sun, 19 Feb 2012 09:04:49 +0000 (10:04 +0100)
When updating castleRights in do_move() perform only one
64bit xor with zobCastle[] instead of two.

The trick here is to define zobCastle[] keys of composite
castling rights as a xor combination of the keys of the
single castling rights, instead of 16 independent keys.

Idea from Critter although implementation is different.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/position.cpp

index 9fa7c7294fdb3425da5cdfffd9be792850fd94f8..ef510766afcd592e8e29b19f0e88a464447b51b9 100644 (file)
@@ -843,9 +843,9 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
   if (    st->castleRights != CASTLES_NONE
       && (castleRightsMask[from] & castleRightsMask[to]) != ALL_CASTLES)
   {
-      k ^= zobCastle[st->castleRights];
-      st->castleRights &= castleRightsMask[from] & castleRightsMask[to];
-      k ^= zobCastle[st->castleRights];
+      int cr = castleRightsMask[from] & castleRightsMask[to];
+      k ^= zobCastle[st->castleRights & (cr ^ ALL_CASTLES)];
+      st->castleRights &= cr;
   }
 
   // Prefetch TT access as soon as we know key is updated
@@ -1151,9 +1151,9 @@ void Position::do_castle_move(Move m) {
       }
 
       // Update castling rights
-      st->key ^= zobCastle[st->castleRights];
-      st->castleRights &= castleRightsMask[kfrom];
-      st->key ^= zobCastle[st->castleRights];
+      int cr = castleRightsMask[kfrom];
+      st->key ^= zobCastle[st->castleRights & (cr ^ ALL_CASTLES)];
+      st->castleRights &= cr;
 
       // Update checkers BB
       st->checkersBB = attackers_to(king_square(~us)) & pieces(us);
@@ -1545,8 +1545,15 @@ void Position::init() {
   for (Square s = SQ_A1; s <= SQ_H8; s++)
       zobEp[s] = rk.rand<Key>();
 
-  for (int i = 0; i < 16; i++)
-      zobCastle[i] = rk.rand<Key>();
+  for (int cr = CASTLES_NONE; cr <= ALL_CASTLES; cr++)
+  {
+      Bitboard b = cr;
+      while (b)
+      {
+          Key k = zobCastle[1 << pop_1st_bit(&b)];
+          zobCastle[cr] ^= k ? k : rk.rand<Key>();
+      }
+  }
 
   zobSideToMove = rk.rand<Key>();
   zobExclusion  = rk.rand<Key>();