]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Move prefetch() out of TT
[stockfish] / src / position.cpp
index abfbc9999721d2d6b9ead408c861500db11221fa..a069cf404be6d012a7ac129c4386b0c3a1721586 100644 (file)
@@ -47,7 +47,6 @@ using std::string;
 Key Position::zobrist[2][8][64];
 Key Position::zobEp[64];
 Key Position::zobCastle[16];
-Key Position::zobMaterial[2][8][16];
 Key Position::zobSideToMove;
 Key Position::zobExclusion;
 
@@ -75,23 +74,23 @@ CheckInfo::CheckInfo(const Position& pos) {
 }
 
 
-/// Position c'tors. Here we always create a slower but safer copy of
-/// the original position or the FEN string, we want the new born Position
-/// object do not depend on any external data. Instead if we know what we
-/// are doing and we need speed we can create a position with default
-/// c'tor Position() and then use just fast_copy().
+/// Position c'tors. Here we always create a copy of the original position
+/// or the FEN string, we want the new born Position object do not depend
+/// on any external data so we detach state pointer from the source one.
 
-Position::Position() {}
+Position::Position(int th) : threadID(th) {}
 
-Position::Position(const Position& pos) {
+Position::Position(const Position& pos, int th) {
 
   memcpy(this, &pos, sizeof(Position));
   detach(); // Always detach() in copy c'tor to avoid surprises
+  threadID = th;
 }
 
-Position::Position(const string& fen) {
+Position::Position(const string& fen, int th) {
 
   from_fen(fen);
+  threadID = th;
 }
 
 
@@ -341,7 +340,7 @@ void Position::print(Move m) const {
   std::cout << std::endl;
   if (m != MOVE_NONE)
   {
-      Position p(*this);
+      Position p(*this, thread());
       string col = (color_of_piece_on(move_from(m)) == BLACK ? ".." : "");
       std::cout << "Move is: " << col << move_to_san(p, m) << std::endl;
   }
@@ -704,7 +703,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
   // pointer to point to the new, ready to be updated, state.
   struct ReducedStateInfo {
     Key pawnKey, materialKey;
-    int castleRights, rule50, pliesFromNull;
+    int castleRights, rule50, gamePly, pliesFromNull;
     Square epSquare;
     Score value;
     Value npMaterial[2];
@@ -716,8 +715,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
 
   // Save the current key to the history[] array, in order to be able to
   // detect repetition draws.
-  history[gamePly] = key;
-  gamePly++;
+  history[st->gamePly++] = key;
 
   // Update side to move
   key ^= zobSideToMove;
@@ -774,7 +772,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
   }
 
   // Prefetch TT access as soon as we know key is updated
-  TT.prefetch(key);
+  prefetch((char*)TT.first_entry(key));
 
   // Move the piece
   Bitboard move_bb = make_move_bb(from, to);
@@ -809,6 +807,46 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
               key ^= zobEp[st->epSquare];
           }
       }
+
+      if (pm) // promotion ?
+      {
+          PieceType promotion = move_promotion_piece(m);
+
+          assert(promotion >= KNIGHT && promotion <= QUEEN);
+
+          // Insert promoted piece instead of pawn
+          clear_bit(&(byTypeBB[PAWN]), to);
+          set_bit(&(byTypeBB[promotion]), to);
+          board[to] = piece_of_color_and_type(us, promotion);
+
+          // Update piece counts
+          pieceCount[us][promotion]++;
+          pieceCount[us][PAWN]--;
+
+          // Update material key
+          st->materialKey ^= zobrist[us][PAWN][pieceCount[us][PAWN]];
+          st->materialKey ^= zobrist[us][promotion][pieceCount[us][promotion]-1];
+
+          // Update piece lists, move the last pawn at index[to] position
+          // and shrink the list. Add a new promotion piece to the list.
+          Square lastPawnSquare = pieceList[us][PAWN][pieceCount[us][PAWN]];
+          index[lastPawnSquare] = index[to];
+          pieceList[us][PAWN][index[lastPawnSquare]] = lastPawnSquare;
+          pieceList[us][PAWN][pieceCount[us][PAWN]] = SQ_NONE;
+          index[to] = pieceCount[us][promotion] - 1;
+          pieceList[us][promotion][index[to]] = to;
+
+          // Partially revert hash keys update
+          key ^= zobrist[us][PAWN][to] ^ zobrist[us][promotion][to];
+          st->pawnKey ^= zobrist[us][PAWN][to];
+
+          // Partially revert and update incremental scores
+          st->value -= pst(us, PAWN, to);
+          st->value += pst(us, promotion, to);
+
+          // Update material
+          st->npMaterial[us] += piece_value_midgame(promotion);
+      }
   }
 
   // Update incremental scores
@@ -817,46 +855,6 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
   // Set capture piece
   st->capture = capture;
 
-  if (pm) // promotion ?
-  {
-      PieceType promotion = move_promotion_piece(m);
-
-      assert(promotion >= KNIGHT && promotion <= QUEEN);
-
-      // Insert promoted piece instead of pawn
-      clear_bit(&(byTypeBB[PAWN]), to);
-      set_bit(&(byTypeBB[promotion]), to);
-      board[to] = piece_of_color_and_type(us, promotion);
-
-      // Update material key
-      st->materialKey ^= zobMaterial[us][PAWN][pieceCount[us][PAWN]];
-      st->materialKey ^= zobMaterial[us][promotion][pieceCount[us][promotion]+1];
-
-      // Update piece counts
-      pieceCount[us][PAWN]--;
-      pieceCount[us][promotion]++;
-
-      // Update piece lists, move the last pawn at index[to] position
-      // and shrink the list. Add a new promotion piece to the list.
-      Square lastPawnSquare = pieceList[us][PAWN][pieceCount[us][PAWN]];
-      index[lastPawnSquare] = index[to];
-      pieceList[us][PAWN][index[lastPawnSquare]] = lastPawnSquare;
-      pieceList[us][PAWN][pieceCount[us][PAWN]] = SQ_NONE;
-      index[to] = pieceCount[us][promotion] - 1;
-      pieceList[us][promotion][index[to]] = to;
-
-      // Partially revert hash keys update
-      key ^= zobrist[us][PAWN][to] ^ zobrist[us][promotion][to];
-      st->pawnKey ^= zobrist[us][PAWN][to];
-
-      // Partially revert and update incremental scores
-      st->value -= pst(us, PAWN, to);
-      st->value += pst(us, promotion, to);
-
-      // Update material
-      st->npMaterial[us] += piece_value_midgame(promotion);
-  }
-
   // Update the key with the final value
   st->key = key;
 
@@ -902,17 +900,25 @@ void Position::do_capture_move(Key& key, PieceType capture, Color them, Square t
 
     Square capsq = to;
 
-    if (ep) // en passant ?
+    // If the captured piece was a pawn, update pawn hash key,
+    // otherwise update non-pawn material.
+    if (capture == PAWN)
     {
-        capsq = (them == BLACK)? (to - DELTA_N) : (to - DELTA_S);
+        if (ep) // en passant ?
+        {
+            capsq = (them == BLACK)? (to - DELTA_N) : (to - DELTA_S);
 
-        assert(to == st->epSquare);
-        assert(relative_rank(opposite_color(them), to) == RANK_6);
-        assert(piece_on(to) == EMPTY);
-        assert(piece_on(capsq) == piece_of_color_and_type(them, PAWN));
+            assert(to == st->epSquare);
+            assert(relative_rank(opposite_color(them), to) == RANK_6);
+            assert(piece_on(to) == EMPTY);
+            assert(piece_on(capsq) == piece_of_color_and_type(them, PAWN));
 
-        board[capsq] = EMPTY;
+            board[capsq] = EMPTY;
+        }
+        st->pawnKey ^= zobrist[them][PAWN][capsq];
     }
+    else
+        st->npMaterial[them] -= piece_value_midgame(capture);
 
     // Remove captured piece
     clear_bit(&(byColorBB[them]), capsq);
@@ -925,19 +931,12 @@ void Position::do_capture_move(Key& key, PieceType capture, Color them, Square t
     // Update incremental scores
     st->value -= pst(them, capture, capsq);
 
-    // If the captured piece was a pawn, update pawn hash key,
-    // otherwise update non-pawn material.
-    if (capture == PAWN)
-        st->pawnKey ^= zobrist[them][PAWN][capsq];
-    else
-        st->npMaterial[them] -= piece_value_midgame(capture);
-
-    // Update material hash key
-    st->materialKey ^= zobMaterial[them][capture][pieceCount[them][capture]];
-
     // Update piece count
     pieceCount[them][capture]--;
 
+    // Update material hash key
+    st->materialKey ^= zobrist[them][capture][pieceCount[them][capture]];
+
     // Update piece list, move the last piece at index[capsq] position
     //
     // WARNING: This is a not perfectly revresible operation. When we
@@ -1061,7 +1060,6 @@ void Position::undo_move(Move m) {
   assert(is_ok());
   assert(move_is_ok(m));
 
-  gamePly--;
   sideToMove = opposite_color(sideToMove);
 
   if (move_is_castle(m))
@@ -1111,7 +1109,6 @@ void Position::undo_move(Move m) {
       pieceList[us][PAWN][index[to]] = to;
   }
 
-
   // Put the piece back at the source square
   Bitboard move_bb = make_move_bb(to, from);
   do_move_bb(&(byColorBB[us]), move_bb);
@@ -1246,21 +1243,20 @@ void Position::do_null_move(StateInfo& backupSt) {
 
   // Save the current key to the history[] array, in order to be able to
   // detect repetition draws.
-  history[gamePly] = st->key;
+  history[st->gamePly++] = st->key;
 
   // Update the necessary information
   if (st->epSquare != SQ_NONE)
       st->key ^= zobEp[st->epSquare];
 
   st->key ^= zobSideToMove;
-  TT.prefetch(st->key);
+  prefetch((char*)TT.first_entry(st->key));
 
   sideToMove = opposite_color(sideToMove);
   st->epSquare = SQ_NONE;
   st->rule50++;
   st->pliesFromNull = 0;
   st->value += (sideToMove == WHITE) ?  TempoValue : -TempoValue;
-  gamePly++;
 }
 
 
@@ -1282,7 +1278,7 @@ void Position::undo_null_move() {
   // Update the necessary information
   sideToMove = opposite_color(sideToMove);
   st->rule50--;
-  gamePly--;
+  st->gamePly--;
 }
 
 
@@ -1479,7 +1475,6 @@ void Position::clear() {
           pieceList[0][i][j] = pieceList[1][i][j] = SQ_NONE;
 
   sideToMove = WHITE;
-  gamePly = 0;
   initialKFile = FILE_E;
   initialKRFile = FILE_H;
   initialQRFile = FILE_A;
@@ -1494,7 +1489,7 @@ void Position::clear() {
 
 void Position::reset_game_ply() {
 
-  gamePly = 0;
+  st->gamePly = 0;
 }
 
 
@@ -1598,8 +1593,8 @@ Key Position::compute_material_key() const {
       for (PieceType pt = PAWN; pt <= QUEEN; pt++)
       {
           int count = piece_count(c, pt);
-          for (int i = 0; i <= count; i++)
-              result ^= zobMaterial[c][pt][i];
+          for (int i = 0; i < count; i++)
+              result ^= zobrist[c][pt][i];
       }
   return result;
 }
@@ -1672,8 +1667,8 @@ bool Position::is_draw() const {
       return true;
 
   // Draw by repetition?
-  for (int i = 4; i <= Min(Min(gamePly, st->rule50), st->pliesFromNull); i += 2)
-      if (history[gamePly - i] == st->key)
+  for (int i = 4, e = Min(Min(st->gamePly, st->rule50), st->pliesFromNull); i <= e; i += 2)
+      if (history[st->gamePly - i] == st->key)
           return true;
 
   return false;
@@ -1752,15 +1747,6 @@ void Position::init_zobrist() {
       zobCastle[i] = genrand_int64();
 
   zobSideToMove = genrand_int64();
-
-  for (int i = 0; i < 2; i++)
-      for (int j = 0; j < 8; j++)
-          for (int k = 0; k < 16; k++)
-              zobMaterial[i][j][k] = (k > 0)? Key(genrand_int64()) : Key(0LL);
-
-  for (int i = 0; i < 16; i++)
-      zobMaterial[0][KING][i] = zobMaterial[1][KING][i] = Key(0ULL);
-
   zobExclusion = genrand_int64();
 }
 
@@ -1797,6 +1783,7 @@ void Position::flipped_copy(const Position& pos) {
   assert(pos.is_ok());
 
   clear();
+  threadID = pos.thread();
 
   // Board
   for (Square s = SQ_A1; s <= SQ_H8; s++)