1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-07-11 19:49:14 +00:00

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 <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2012-04-06 13:46:53 +01:00
parent 699f700162
commit e1919384a2
9 changed files with 48 additions and 63 deletions

View file

@ -107,7 +107,7 @@ void benchmark(istringstream& is) {
for (size_t i = 0; i < fens.size(); i++) 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; cerr << "\nPosition: " << i + 1 << '/' << fens.size() << endl;

View file

@ -77,7 +77,7 @@ namespace {
string fen = sides[0] + char('0' + int(8 - code.length())) string fen = sides[0] + char('0' + int(8 - code.length()))
+ sides[1] + "/8/8/8/8/8/8/8 w - - 0 10"; + 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> template<typename M>

View file

@ -371,7 +371,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
margins[WHITE] = margins[BLACK] = VALUE_ZERO; margins[WHITE] = margins[BLACK] = VALUE_ZERO;
// Probe the material hash table // 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(); score += ei.mi->material_value();
// If we have a specialized evaluation function for the current material // 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 // 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(); score += ei.pi->pawns_value();
// Initialize attack and king safety bitboards // Initialize attack and king safety bitboards

View 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 /// object do not depend on any external data so we detach state pointer from
/// the source one. /// the source one.
void Position::copy(const Position& pos, Thread* th) { Position& Position::operator=(const Position& pos) {
memcpy(this, &pos, sizeof(Position)); memcpy(this, &pos, sizeof(Position));
startState = *st; startState = *st;
st = &startState; st = &startState;
thisThread = th;
nodes = 0; nodes = 0;
return *this;
assert(pos_is_ok());
} }
@ -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 /// string. This function is not very robust - make sure that input FENs are
/// correct (this is assumed to be the responsibility of the GUI). /// 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. 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->npMaterial[BLACK] = compute_non_pawn_material(BLACK);
st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove); st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove);
chess960 = isChess960; chess960 = isChess960;
thisThread = th;
assert(pos_is_ok()); assert(pos_is_ok());
} }
@ -331,7 +328,7 @@ void Position::print(Move move) const {
if (move) if (move)
{ {
Position p(*this, thisThread); Position p(*this);
cout << "\nMove is: " << (sideToMove == BLACK ? ".." : "") << move_to_san(p, move); 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 pawn and material hash tables
prefetch((char*)thisThread->pawnTable.entries[st->pawnKey]); prefetch((char*)Threads.this_thread()->pawnTable.entries[st->pawnKey]);
prefetch((char*)thisThread->materialTable.entries[st->materialKey]); prefetch((char*)Threads.this_thread()->materialTable.entries[st->materialKey]);
// Update incremental scores // Update incremental scores
st->psqScore += psq_delta(piece, from, to); st->psqScore += psq_delta(piece, from, to);
@ -1541,10 +1538,9 @@ void Position::init() {
void Position::flip() { void Position::flip() {
// Make a copy of current position before to start changing // Make a copy of current position before to start changing
const Position pos(*this, thisThread); const Position pos(*this);
clear(); clear();
thisThread = &pos.this_thread();
// Board // Board
for (Square s = SQ_A1; s <= SQ_H8; s++) for (Square s = SQ_A1; s <= SQ_H8; s++)

View file

@ -84,19 +84,14 @@ struct StateInfo {
/// * A counter for detecting 50 move rule draws. /// * A counter for detecting 50 move rule draws.
class Position { class Position {
// No copy c'tor or assignment operator allowed
Position(const Position&);
Position& operator=(const Position&);
public: public:
Position() {} Position() {}
Position(const Position& p, Thread* t) { copy(p, t); } Position(const Position& p) { *this = p; }
Position(const std::string& f, bool c960, Thread* t) { from_fen(f, c960, t); } Position(const std::string& f, bool c960) { from_fen(f, c960); }
Position& operator=(const Position&);
// Text input/output // Text input/output
void copy(const Position& pos, Thread* th); void from_fen(const std::string& fen, bool isChess960);
void from_fen(const std::string& fen, bool isChess960, Thread* th);
const std::string to_fen() const; const std::string to_fen() const;
void print(Move m = MOVE_NONE) const; void print(Move m = MOVE_NONE) const;
@ -176,7 +171,6 @@ public:
Color side_to_move() const; Color side_to_move() const;
int startpos_ply_counter() const; int startpos_ply_counter() const;
bool is_chess960() const; bool is_chess960() const;
Thread& this_thread() const;
int64_t nodes_searched() const; int64_t nodes_searched() const;
void set_nodes_searched(int64_t n); void set_nodes_searched(int64_t n);
template<bool SkipRepetition> bool is_draw() const; template<bool SkipRepetition> bool is_draw() const;
@ -224,7 +218,6 @@ private:
int64_t nodes; int64_t nodes;
int startPosPly; int startPosPly;
Color sideToMove; Color sideToMove;
Thread* thisThread;
StateInfo* st; StateInfo* st;
int chess960; int chess960;
@ -434,8 +427,4 @@ inline PieceType Position::captured_piece_type() const {
return st->capturedType; return st->capturedType;
} }
inline Thread& Position::this_thread() const {
return *thisThread;
}
#endif // !defined(POSITION_H_INCLUDED) #endif // !defined(POSITION_H_INCLUDED)

View file

@ -332,7 +332,7 @@ finalize:
// but if we are pondering or in infinite search, we shouldn't print the best // but if we are pondering or in infinite search, we shouldn't print the best
// move before we are told to do so. // move before we are told to do so.
if (!Signals.stop && (Limits.ponder || Limits.infinite)) 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 // Best move could be MOVE_NONE when searching on a stalemate position
cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], Chess960) cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], Chess960)
@ -543,7 +543,7 @@ namespace {
bool isPvMove, inCheck, singularExtensionNode, givesCheck; bool isPvMove, inCheck, singularExtensionNode, givesCheck;
bool captureOrPromotion, dangerous, doFullDepthSearch; bool captureOrPromotion, dangerous, doFullDepthSearch;
int moveCount = 0, playedMoveCount = 0; int moveCount = 0, playedMoveCount = 0;
Thread& thread = pos.this_thread(); Thread* thisThread = Threads.this_thread();
SplitPoint* sp = NULL; SplitPoint* sp = NULL;
refinedValue = bestValue = value = -VALUE_INFINITE; refinedValue = bestValue = value = -VALUE_INFINITE;
@ -552,8 +552,8 @@ namespace {
ss->ply = (ss-1)->ply + 1; ss->ply = (ss-1)->ply + 1;
// Used to send selDepth info to GUI // Used to send selDepth info to GUI
if (PvNode && thread.maxPly < ss->ply) if (PvNode && thisThread->maxPly < ss->ply)
thread.maxPly = ss->ply; thisThread->maxPly = ss->ply;
// Step 1. Initialize node // Step 1. Initialize node
if (SpNode) 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 // Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
while ( bestValue < beta while ( bestValue < beta
&& (move = mp.next_move()) != MOVE_NONE && (move = mp.next_move()) != MOVE_NONE
&& !thread.cutoff_occurred() && !thisThread->cutoff_occurred()
&& !Signals.stop) && !Signals.stop)
{ {
assert(is_ok(move)); assert(is_ok(move));
@ -846,7 +846,7 @@ split_point_start: // At split points actual search starts from here
{ {
Signals.firstRootMove = (moveCount == 1); 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 cout << "info depth " << depth / ONE_PLY
<< " currmove " << move_to_uci(move, Chess960) << " currmove " << move_to_uci(move, Chess960)
<< " currmovenumber " << moveCount + PVIdx << endl; << " 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 && value < beta) // We want always alpha < beta
alpha = value; alpha = value;
if (SpNode && !thread.cutoff_occurred()) if (SpNode && !thisThread->cutoff_occurred())
{ {
sp->bestValue = value; sp->bestValue = value;
sp->bestMove = move; sp->bestMove = move;
@ -1053,9 +1053,9 @@ split_point_start: // At split points actual search starts from here
if ( !SpNode if ( !SpNode
&& depth >= Threads.min_split_depth() && depth >= Threads.min_split_depth()
&& bestValue < beta && bestValue < beta
&& Threads.available_slave_exists(thread) && Threads.available_slave_exists(thisThread)
&& !Signals.stop && !Signals.stop
&& !thread.cutoff_occurred()) && !thisThread->cutoff_occurred())
bestValue = Threads.split<FakeSplit>(pos, ss, alpha, beta, bestValue, &bestMove, bestValue = Threads.split<FakeSplit>(pos, ss, alpha, beta, bestValue, &bestMove,
depth, threatMove, moveCount, &mp, NT); depth, threatMove, moveCount, &mp, NT);
} }
@ -1079,7 +1079,7 @@ split_point_start: // At split points actual search starts from here
// Step 21. Update tables // Step 21. Update tables
// Update transposition table entry, killers and history // 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; move = bestValue <= oldAlpha ? MOVE_NONE : bestMove;
bt = bestValue <= oldAlpha ? BOUND_UPPER bt = bestValue <= oldAlpha ? BOUND_UPPER
@ -1825,7 +1825,7 @@ void Thread::idle_loop(SplitPoint* sp_master) {
lock_release(Threads.splitLock); lock_release(Threads.splitLock);
Stack ss[MAX_PLY_PLUS_2]; Stack ss[MAX_PLY_PLUS_2];
Position pos(*sp->pos, this); Position pos(*sp->pos);
Thread* master = sp->master; Thread* master = sp->master;
memcpy(ss, sp->ss - 1, 4 * sizeof(Stack)); memcpy(ss, sp->ss - 1, 4 * sizeof(Stack));

View file

@ -183,7 +183,7 @@ bool Thread::cutoff_occurred() const {
// slaves which are busy searching the split point at the top of slaves split // slaves which are busy searching the split point at the top of slaves split
// point stack (the "helpful master concept" in YBWC terminology). // 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) if (is_searching)
return false; 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 // 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. // 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 // available_slave_exists() tries to find an idle thread which is available as
// a slave for the thread 'master'. // 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++) for (int i = 0; i < size(); i++)
if (threads[i]->is_available_to(master)) 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(beta <= VALUE_INFINITE);
assert(depth > DEPTH_ZERO); 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; return bestValue;
// Pick the next available split point from the split point stack // 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->parent = master->curSplitPoint;
sp->master = &master; sp->master = master;
sp->cutoff = false; sp->cutoff = false;
sp->slavesMask = 1ULL << master.idx; sp->slavesMask = 1ULL << master->idx;
sp->depth = depth; sp->depth = depth;
sp->bestMove = *bestMove; sp->bestMove = *bestMove;
sp->threatMove = threatMove; sp->threatMove = threatMove;
@ -338,9 +338,9 @@ Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta,
sp->nodes = 0; sp->nodes = 0;
sp->ss = ss; sp->ss = ss;
assert(master.is_searching); assert(master->is_searching);
master.curSplitPoint = sp; master->curSplitPoint = sp;
int slavesCnt = 0; int slavesCnt = 0;
// Try to allocate available threads and ask them to start searching setting // 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. // their work at this split point.
if (slavesCnt || Fake) 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 // 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. // 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 // 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(sp->lock); // To protect sp->nodes
lock_grab(splitLock); lock_grab(splitLock);
master.is_searching = true; master->is_searching = true;
master.splitPointsCnt--; master->splitPointsCnt--;
master.curSplitPoint = sp->parent; master->curSplitPoint = sp->parent;
pos.set_nodes_searched(pos.nodes_searched() + sp->nodes); pos.set_nodes_searched(pos.nodes_searched() + sp->nodes);
*bestMove = sp->bestMove; *bestMove = sp->bestMove;
@ -440,7 +440,7 @@ void ThreadsManager::start_searching(const Position& pos, const LimitsType& limi
Signals.stopOnPonderhit = Signals.firstRootMove = false; Signals.stopOnPonderhit = Signals.firstRootMove = false;
Signals.stop = Signals.failedLowAtRoot = false; Signals.stop = Signals.failedLowAtRoot = false;
RootPosition.copy(pos, main_thread()); RootPosition = pos;
Limits = limits; Limits = limits;
RootMoves.clear(); RootMoves.clear();

View file

@ -78,7 +78,7 @@ public:
void wake_up(); void wake_up();
bool cutoff_occurred() const; 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(SplitPoint* sp_master);
void idle_loop() { idle_loop(NULL); } // Hack to allow storing in start_fn void idle_loop() { idle_loop(NULL); } // Hack to allow storing in start_fn
void main_loop(); void main_loop();
@ -126,7 +126,7 @@ public:
void wake_up() const; void wake_up() const;
void sleep() const; void sleep() const;
void read_uci_options(); 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 set_timer(int msec);
void wait_for_search_finished(); void wait_for_search_finished();
void start_searching(const Position& pos, const Search::LimitsType& limits, void start_searching(const Position& pos, const Search::LimitsType& limits,

View file

@ -56,7 +56,7 @@ namespace {
void uci_loop(const string& args) { 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; string cmd, token;
while (token != "quit") while (token != "quit")
@ -167,7 +167,7 @@ namespace {
else else
return; return;
pos.from_fen(fen, Options["UCI_Chess960"], Threads.main_thread()); pos.from_fen(fen, Options["UCI_Chess960"]);
// Parse move list (if any) // Parse move list (if any)
while (is >> token && (m = move_from_uci(pos, token)) != MOVE_NONE) while (is >> token && (m = move_from_uci(pos, token)) != MOVE_NONE)