Don't store Thread info in Position
authorMarco Costalba <mcostalba@gmail.com>
Fri, 6 Apr 2012 12:46:53 +0000 (13:46 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Fri, 6 Apr 2012 13:36:45 +0000 (14:36 +0100)
But use the newly introduced local storage
for this. A good code semplification and also
the correct way to go.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/benchmark.cpp
src/endgame.cpp
src/evaluate.cpp
src/position.cpp
src/position.h
src/search.cpp
src/thread.cpp
src/thread.h
src/uci.cpp

index f42c0e6..6ac64d4 100644 (file)
@@ -107,7 +107,7 @@ void benchmark(istringstream& is) {
 
   for (size_t i = 0; i < fens.size(); i++)
   {
-      Position pos(fens[i], false, NULL);
+      Position pos(fens[i], false);
 
       cerr << "\nPosition: " << i + 1 << '/' << fens.size() << endl;
 
index 5e021f1..65f0f40 100644 (file)
@@ -77,7 +77,7 @@ namespace {
     string fen =  sides[0] + char('0' + int(8 - code.length()))
                 + sides[1] + "/8/8/8/8/8/8/8 w - - 0 10";
 
-    return Position(fen, false, NULL).material_key();
+    return Position(fen, false).material_key();
   }
 
   template<typename M>
index db5e3fc..520c33e 100644 (file)
@@ -371,7 +371,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
   margins[WHITE] = margins[BLACK] = VALUE_ZERO;
 
   // Probe the material hash table
-  ei.mi = pos.this_thread().materialTable.probe(pos);
+  ei.mi = Threads.this_thread()->materialTable.probe(pos);
   score += ei.mi->material_value();
 
   // If we have a specialized evaluation function for the current material
@@ -383,7 +383,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
   }
 
   // Probe the pawn hash table
-  ei.pi = pos.this_thread().pawnTable.probe(pos);
+  ei.pi = Threads.this_thread()->pawnTable.probe(pos);
   score += ei.pi->pawns_value();
 
   // Initialize attack and king safety bitboards
index 72a261d..62749a9 100644 (file)
@@ -92,19 +92,17 @@ CheckInfo::CheckInfo(const Position& pos) {
 }
 
 
-/// Position::copy() creates a copy of 'pos'. We want the new born Position
+/// Position::operator=() creates a copy of 'pos'. We want the new born Position
 /// object do not depend on any external data so we detach state pointer from
 /// the source one.
 
-void Position::copy(const Position& pos, Thread* th) {
+Position& Position::operator=(const Position& pos) {
 
   memcpy(this, &pos, sizeof(Position));
   startState = *st;
   st = &startState;
-  thisThread = th;
   nodes = 0;
-
-  assert(pos_is_ok());
+  return *this;
 }
 
 
@@ -112,7 +110,7 @@ void Position::copy(const Position& pos, Thread* th) {
 /// string. This function is not very robust - make sure that input FENs are
 /// correct (this is assumed to be the responsibility of the GUI).
 
-void Position::from_fen(const string& fenStr, bool isChess960, Thread* th) {
+void Position::from_fen(const string& fenStr, bool isChess960) {
 /*
    A FEN string defines a particular position using only the ASCII character set.
 
@@ -228,7 +226,6 @@ void Position::from_fen(const string& fenStr, bool isChess960, Thread* th) {
   st->npMaterial[BLACK] = compute_non_pawn_material(BLACK);
   st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove);
   chess960 = isChess960;
-  thisThread = th;
 
   assert(pos_is_ok());
 }
@@ -331,7 +328,7 @@ void Position::print(Move move) const {
 
   if (move)
   {
-      Position p(*this, thisThread);
+      Position p(*this);
       cout << "\nMove is: " << (sideToMove == BLACK ? ".." : "") << move_to_san(p, move);
   }
 
@@ -898,8 +895,8 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
   }
 
   // Prefetch pawn and material hash tables
-  prefetch((char*)thisThread->pawnTable.entries[st->pawnKey]);
-  prefetch((char*)thisThread->materialTable.entries[st->materialKey]);
+  prefetch((char*)Threads.this_thread()->pawnTable.entries[st->pawnKey]);
+  prefetch((char*)Threads.this_thread()->materialTable.entries[st->materialKey]);
 
   // Update incremental scores
   st->psqScore += psq_delta(piece, from, to);
@@ -1541,10 +1538,9 @@ void Position::init() {
 void Position::flip() {
 
   // Make a copy of current position before to start changing
-  const Position pos(*this, thisThread);
+  const Position pos(*this);
 
   clear();
-  thisThread = &pos.this_thread();
 
   // Board
   for (Square s = SQ_A1; s <= SQ_H8; s++)
index 4713094..2db3d96 100644 (file)
@@ -84,19 +84,14 @@ struct StateInfo {
 ///    * A counter for detecting 50 move rule draws.
 
 class Position {
-
-  // No copy c'tor or assignment operator allowed
-  Position(const Position&);
-  Position& operator=(const Position&);
-
 public:
   Position() {}
-  Position(const Position& p, Thread* t) { copy(p, t); }
-  Position(const std::string& f, bool c960, Thread* t) { from_fen(f, c960, t); }
+  Position(const Position& p) { *this = p; }
+  Position(const std::string& f, bool c960) { from_fen(f, c960); }
+  Position& operator=(const Position&);
 
   // Text input/output
-  void copy(const Position& pos, Thread* th);
-  void from_fen(const std::string& fen, bool isChess960, Thread* th);
+  void from_fen(const std::string& fen, bool isChess960);
   const std::string to_fen() const;
   void print(Move m = MOVE_NONE) const;
 
@@ -176,7 +171,6 @@ public:
   Color side_to_move() const;
   int startpos_ply_counter() const;
   bool is_chess960() const;
-  Thread& this_thread() const;
   int64_t nodes_searched() const;
   void set_nodes_searched(int64_t n);
   template<bool SkipRepetition> bool is_draw() const;
@@ -224,7 +218,6 @@ private:
   int64_t nodes;
   int startPosPly;
   Color sideToMove;
-  Thread* thisThread;
   StateInfo* st;
   int chess960;
 
@@ -434,8 +427,4 @@ inline PieceType Position::captured_piece_type() const {
   return st->capturedType;
 }
 
-inline Thread& Position::this_thread() const {
-  return *thisThread;
-}
-
 #endif // !defined(POSITION_H_INCLUDED)
index 94fa063..3711440 100644 (file)
@@ -332,7 +332,7 @@ finalize:
   // but if we are pondering or in infinite search, we shouldn't print the best
   // move before we are told to do so.
   if (!Signals.stop && (Limits.ponder || Limits.infinite))
-      pos.this_thread().wait_for_stop_or_ponderhit();
+      Threads.this_thread()->wait_for_stop_or_ponderhit();
 
   // Best move could be MOVE_NONE when searching on a stalemate position
   cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], Chess960)
@@ -543,7 +543,7 @@ namespace {
     bool isPvMove, inCheck, singularExtensionNode, givesCheck;
     bool captureOrPromotion, dangerous, doFullDepthSearch;
     int moveCount = 0, playedMoveCount = 0;
-    Thread& thread = pos.this_thread();
+    Thread* thisThread = Threads.this_thread();
     SplitPoint* sp = NULL;
 
     refinedValue = bestValue = value = -VALUE_INFINITE;
@@ -552,8 +552,8 @@ namespace {
     ss->ply = (ss-1)->ply + 1;
 
     // Used to send selDepth info to GUI
-    if (PvNode && thread.maxPly < ss->ply)
-        thread.maxPly = ss->ply;
+    if (PvNode && thisThread->maxPly < ss->ply)
+        thisThread->maxPly = ss->ply;
 
     // Step 1. Initialize node
     if (SpNode)
@@ -816,7 +816,7 @@ split_point_start: // At split points actual search starts from here
     // Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
     while (   bestValue < beta
            && (move = mp.next_move()) != MOVE_NONE
-           && !thread.cutoff_occurred()
+           && !thisThread->cutoff_occurred()
            && !Signals.stop)
     {
       assert(is_ok(move));
@@ -846,7 +846,7 @@ split_point_start: // At split points actual search starts from here
       {
           Signals.firstRootMove = (moveCount == 1);
 
-          if (&thread == Threads.main_thread() && SearchTime.elapsed() > 2000)
+          if (thisThread == Threads.main_thread() && SearchTime.elapsed() > 2000)
               cout << "info depth " << depth / ONE_PLY
                    << " currmove " << move_to_uci(move, Chess960)
                    << " currmovenumber " << moveCount + PVIdx << endl;
@@ -1038,7 +1038,7 @@ split_point_start: // At split points actual search starts from here
               && value < beta) // We want always alpha < beta
               alpha = value;
 
-          if (SpNode && !thread.cutoff_occurred())
+          if (SpNode && !thisThread->cutoff_occurred())
           {
               sp->bestValue = value;
               sp->bestMove = move;
@@ -1053,9 +1053,9 @@ split_point_start: // At split points actual search starts from here
       if (   !SpNode
           && depth >= Threads.min_split_depth()
           && bestValue < beta
-          && Threads.available_slave_exists(thread)
+          && Threads.available_slave_exists(thisThread)
           && !Signals.stop
-          && !thread.cutoff_occurred())
+          && !thisThread->cutoff_occurred())
           bestValue = Threads.split<FakeSplit>(pos, ss, alpha, beta, bestValue, &bestMove,
                                                depth, threatMove, moveCount, &mp, NT);
     }
@@ -1079,7 +1079,7 @@ split_point_start: // At split points actual search starts from here
 
     // Step 21. Update tables
     // Update transposition table entry, killers and history
-    if (!SpNode && !Signals.stop && !thread.cutoff_occurred())
+    if (!SpNode && !Signals.stop && !thisThread->cutoff_occurred())
     {
         move = bestValue <= oldAlpha ? MOVE_NONE : bestMove;
         bt   = bestValue <= oldAlpha ? BOUND_UPPER
@@ -1825,7 +1825,7 @@ void Thread::idle_loop(SplitPoint* sp_master) {
           lock_release(Threads.splitLock);
 
           Stack ss[MAX_PLY_PLUS_2];
-          Position pos(*sp->pos, this);
+          Position pos(*sp->pos);
           Thread* master = sp->master;
 
           memcpy(ss, sp->ss - 1, 4 * sizeof(Stack));
index b8686f4..5136a23 100644 (file)
@@ -183,7 +183,7 @@ bool Thread::cutoff_occurred() const {
 // slaves which are busy searching the split point at the top of slaves split
 // point stack (the "helpful master concept" in YBWC terminology).
 
-bool Thread::is_available_to(const Thread& master) const {
+bool Thread::is_available_to(Thread* master) const {
 
   if (is_searching)
       return false;
@@ -194,7 +194,7 @@ bool Thread::is_available_to(const Thread& master) const {
 
   // No active split points means that the thread is available as a slave for any
   // other thread otherwise apply the "helpful master" concept if possible.
-  return !spCnt || (splitPoints[spCnt - 1].slavesMask & (1ULL << master.idx));
+  return !spCnt || (splitPoints[spCnt - 1].slavesMask & (1ULL << master->idx));
 }
 
 
@@ -283,7 +283,7 @@ void ThreadsManager::sleep() const {
 // available_slave_exists() tries to find an idle thread which is available as
 // a slave for the thread 'master'.
 
-bool ThreadsManager::available_slave_exists(const Thread& master) const {
+bool ThreadsManager::available_slave_exists(Thread* master) const {
 
   for (int i = 0; i < size(); i++)
       if (threads[i]->is_available_to(master))
@@ -313,18 +313,18 @@ Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta,
   assert(beta <= VALUE_INFINITE);
   assert(depth > DEPTH_ZERO);
 
-  Thread& master = pos.this_thread();
+  Thread* master = Threads.this_thread();
 
-  if (master.splitPointsCnt >= MAX_SPLITPOINTS_PER_THREAD)
+  if (master->splitPointsCnt >= MAX_SPLITPOINTS_PER_THREAD)
       return bestValue;
 
   // Pick the next available split point from the split point stack
-  SplitPoint* sp = &master.splitPoints[master.splitPointsCnt++];
+  SplitPoint* sp = &master->splitPoints[master->splitPointsCnt++];
 
-  sp->parent = master.curSplitPoint;
-  sp->master = &master;
+  sp->parent = master->curSplitPoint;
+  sp->master = master;
   sp->cutoff = false;
-  sp->slavesMask = 1ULL << master.idx;
+  sp->slavesMask = 1ULL << master->idx;
   sp->depth = depth;
   sp->bestMove = *bestMove;
   sp->threatMove = threatMove;
@@ -338,9 +338,9 @@ Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta,
   sp->nodes = 0;
   sp->ss = ss;
 
-  assert(master.is_searching);
+  assert(master->is_searching);
 
-  master.curSplitPoint = sp;
+  master->curSplitPoint = sp;
   int slavesCnt = 0;
 
   // Try to allocate available threads and ask them to start searching setting
@@ -373,11 +373,11 @@ Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta,
   // their work at this split point.
   if (slavesCnt || Fake)
   {
-      master.idle_loop(sp);
+      master->idle_loop(sp);
 
       // In helpful master concept a master can help only a sub-tree of its split
       // point, and because here is all finished is not possible master is booked.
-      assert(!master.is_searching);
+      assert(!master->is_searching);
   }
 
   // We have returned from the idle loop, which means that all threads are
@@ -386,9 +386,9 @@ Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta,
   lock_grab(sp->lock); // To protect sp->nodes
   lock_grab(splitLock);
 
-  master.is_searching = true;
-  master.splitPointsCnt--;
-  master.curSplitPoint = sp->parent;
+  master->is_searching = true;
+  master->splitPointsCnt--;
+  master->curSplitPoint = sp->parent;
   pos.set_nodes_searched(pos.nodes_searched() + sp->nodes);
   *bestMove = sp->bestMove;
 
@@ -440,7 +440,7 @@ void ThreadsManager::start_searching(const Position& pos, const LimitsType& limi
   Signals.stopOnPonderhit = Signals.firstRootMove = false;
   Signals.stop = Signals.failedLowAtRoot = false;
 
-  RootPosition.copy(pos, main_thread());
+  RootPosition = pos;
   Limits = limits;
   RootMoves.clear();
 
index 3f3c8c4..c39c6e6 100644 (file)
@@ -78,7 +78,7 @@ public:
 
   void wake_up();
   bool cutoff_occurred() const;
-  bool is_available_to(const Thread& master) const;
+  bool is_available_to(Thread* master) const;
   void idle_loop(SplitPoint* sp_master);
   void idle_loop() { idle_loop(NULL); } // Hack to allow storing in start_fn
   void main_loop();
@@ -126,7 +126,7 @@ public:
   void wake_up() const;
   void sleep() const;
   void read_uci_options();
-  bool available_slave_exists(const Thread& master) const;
+  bool available_slave_exists(Thread* master) const;
   void set_timer(int msec);
   void wait_for_search_finished();
   void start_searching(const Position& pos, const Search::LimitsType& limits,
index c6da2fc..dd4040d 100644 (file)
@@ -56,7 +56,7 @@ namespace {
 
 void uci_loop(const string& args) {
 
-  Position pos(StartFEN, false, Threads.main_thread()); // The root position
+  Position pos(StartFEN, false); // The root position
   string cmd, token;
 
   while (token != "quit")
@@ -167,7 +167,7 @@ namespace {
     else
         return;
 
-    pos.from_fen(fen, Options["UCI_Chess960"], Threads.main_thread());
+    pos.from_fen(fen, Options["UCI_Chess960"]);
 
     // Parse move list (if any)
     while (is >> token && (m = move_from_uci(pos, token)) != MOVE_NONE)