From: Marco Costalba Date: Fri, 6 Apr 2012 12:46:53 +0000 (+0100) Subject: Don't store Thread info in Position X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=e1919384a23fe728422f995369161efa192380db;ds=sidebyside Don't store Thread info in Position 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 --- diff --git a/src/benchmark.cpp b/src/benchmark.cpp index f42c0e6c..6ac64d43 100644 --- a/src/benchmark.cpp +++ b/src/benchmark.cpp @@ -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; diff --git a/src/endgame.cpp b/src/endgame.cpp index 5e021f11..65f0f409 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -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 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index db5e3fc2..520c33e0 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -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 diff --git a/src/position.cpp b/src/position.cpp index 72a261d4..62749a91 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -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++) diff --git a/src/position.h b/src/position.h index 4713094d..2db3d965 100644 --- a/src/position.h +++ b/src/position.h @@ -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 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) diff --git a/src/search.cpp b/src/search.cpp index 94fa063f..37114408 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -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(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)); diff --git a/src/thread.cpp b/src/thread.cpp index b8686f4c..5136a233 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -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(); diff --git a/src/thread.h b/src/thread.h index 3f3c8c4c..c39c6e69 100644 --- a/src/thread.h +++ b/src/thread.h @@ -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, diff --git a/src/uci.cpp b/src/uci.cpp index c6da2fc4..dd4040d7 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -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)