From 800410eef1c0811d046ee2332b3afda21284b876 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Thu, 26 Sep 2013 19:25:50 +0200 Subject: [PATCH] Use a per-thread array for generated moves This greately reduces stack usage and is a prerequisite for next patch. Verified with 40K games both in single and SMP case that there are no regressions. No functional change. --- src/movepick.cpp | 9 ++++++--- src/movepick.h | 4 ++-- src/thread.cpp | 3 ++- src/thread.h | 4 ++++ 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/movepick.cpp b/src/movepick.cpp index 643c8368..a54398c0 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -75,7 +75,7 @@ MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats& assert(d > DEPTH_ZERO); - cur = end = moves; + cur = end = moves = pos.this_thread()->get_moves_array(); endBadCaptures = moves + MAX_MOVES - 1; countermoves = cm; ss = s; @@ -91,10 +91,11 @@ MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats& } MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats& h, - Square sq) : pos(p), history(h), cur(moves), end(moves) { + Square sq) : pos(p), history(h) { assert(d <= DEPTH_ZERO); + cur = end = moves = pos.this_thread()->get_moves_array(); if (p.checkers()) stage = EVASION; @@ -123,10 +124,11 @@ MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats& } MovePicker::MovePicker(const Position& p, Move ttm, const HistoryStats& h, PieceType pt) - : pos(p), history(h), cur(moves), end(moves) { + : pos(p), history(h) { assert(!pos.checkers()); + cur = end = moves = pos.this_thread()->get_moves_array(); stage = PROBCUT; // In ProbCut we generate only captures better than parent's captured piece @@ -139,6 +141,7 @@ MovePicker::MovePicker(const Position& p, Move ttm, const HistoryStats& h, Piece end += (ttMove != MOVE_NONE); } +MovePicker::~MovePicker() { pos.this_thread()->free_moves_array(); } /// score() assign a numerical move ordering score to each move in a move list. /// The moves with highest scores will be picked first. diff --git a/src/movepick.h b/src/movepick.h index c444615f..f3839bf0 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -87,6 +87,7 @@ public: MovePicker(const Position&, Move, Depth, const HistoryStats&, Square); MovePicker(const Position&, Move, const HistoryStats&, PieceType); MovePicker(const Position&, Move, Depth, const HistoryStats&, Move*, Search::Stack*); + ~MovePicker(); template Move next_move(); @@ -103,8 +104,7 @@ private: ExtMove killers[4]; Square recaptureSquare; int captureThreshold, stage; - ExtMove *cur, *end, *endQuiets, *endBadCaptures; - ExtMove moves[MAX_MOVES]; + ExtMove *moves, *cur, *end, *endQuiets, *endBadCaptures; }; #endif // #ifndef MOVEPICK_H_INCLUDED diff --git a/src/thread.cpp b/src/thread.cpp index 7d85db86..c385f05e 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -83,10 +83,11 @@ void ThreadBase::wait_for(volatile const bool& b) { Thread::Thread() /* : splitPoints() */ { // Value-initialization bug in MSVC searching = false; - maxPly = splitPointsSize = 0; + maxPly = splitPointsSize = curPage = 0; activeSplitPoint = NULL; activePosition = NULL; idx = Threads.size(); + movePages.resize(MAX_PLY_PLUS_6 * MAX_MOVES); } diff --git a/src/thread.h b/src/thread.h index 56d000f3..64548267 100644 --- a/src/thread.h +++ b/src/thread.h @@ -115,6 +115,8 @@ struct Thread : public ThreadBase { virtual void idle_loop(); bool cutoff_occurred() const; bool is_available_to(const Thread* master) const; + ExtMove* get_moves_array() { return &movePages[curPage += MAX_MOVES]; } + void free_moves_array() { curPage -= MAX_MOVES; } template void split(Position& pos, const Search::Stack* ss, Value alpha, Value beta, Value* bestValue, Move* bestMove, @@ -125,6 +127,8 @@ struct Thread : public ThreadBase { Endgames endgames; Pawns::Table pawnsTable; Position* activePosition; + std::vector movePages; + int curPage; size_t idx; int maxPly; SplitPoint* volatile activeSplitPoint; -- 2.39.2