From 91427c824280d71eaf27f39a4bfdd2188cbdb4ec Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Mon, 4 Feb 2013 22:09:52 +0100 Subject: [PATCH] Move split() under Thread Previous renaming patch suggested this reformat: when a better naming leads to a better code! No functional change. --- src/search.cpp | 4 ++-- src/thread.cpp | 58 ++++++++++++++++++++++++-------------------------- src/thread.h | 10 ++++----- 3 files changed, 35 insertions(+), 37 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 4adcefa9..49d18b50 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1030,8 +1030,8 @@ split_point_start: // At split points actual search starts from here { assert(bestValue < beta); - bestValue = Threads.split(pos, ss, alpha, beta, bestValue, &bestMove, - depth, threatMove, moveCount, mp, NT); + bestValue = thisThread->split(pos, ss, alpha, beta, bestValue, &bestMove, + depth, threatMove, moveCount, mp, NT); if (bestValue >= beta) break; } diff --git a/src/thread.cpp b/src/thread.cpp index 7be8da88..12a95271 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -249,26 +249,24 @@ bool ThreadPool::slave_available(Thread* master) const { // search() then split() returns. template -Value ThreadPool::split(Position& pos, Stack* ss, Value alpha, Value beta, - Value bestValue, Move* bestMove, Depth depth, Move threatMove, - int moveCount, MovePicker& mp, int nodeType) { +Value Thread::split(Position& pos, Stack* ss, Value alpha, Value beta, + Value bestValue, Move* bestMove, Depth depth, Move threatMove, + int moveCount, MovePicker& mp, int nodeType) { assert(pos.pos_is_ok()); assert(bestValue <= alpha && alpha < beta && beta <= VALUE_INFINITE); assert(bestValue > -VALUE_INFINITE); assert(depth >= Threads.minimumSplitDepth); - Thread* thisThread = pos.this_thread(); - - assert(thisThread->searching); - assert(thisThread->splitPointsSize < MAX_SPLITPOINTS_PER_THREAD); + assert(searching); + assert(splitPointsSize < MAX_SPLITPOINTS_PER_THREAD); // Pick the next available split point from the split point stack - SplitPoint& sp = thisThread->splitPoints[thisThread->splitPointsSize]; + SplitPoint& sp = splitPoints[splitPointsSize]; - sp.masterThread = thisThread; - sp.parentSplitPoint = thisThread->activeSplitPoint; - sp.slavesMask = 1ULL << thisThread->idx; + sp.masterThread = this; + sp.parentSplitPoint = activeSplitPoint; + sp.slavesMask = 1ULL << idx; sp.depth = depth; sp.bestMove = *bestMove; sp.threatMove = threatMove; @@ -286,25 +284,25 @@ Value ThreadPool::split(Position& pos, Stack* ss, Value alpha, Value beta, // Try to allocate available threads and ask them to start searching setting // 'searching' flag. This must be done under lock protection to avoid concurrent // allocation of the same slave by another master. - mutex.lock(); + Threads.mutex.lock(); sp.mutex.lock(); - thisThread->splitPointsSize++; - thisThread->activeSplitPoint = &sp; + splitPointsSize++; + activeSplitPoint = &sp; size_t slavesCnt = 1; // Master is always included - for (size_t i = 0; i < threads.size() && !Fake; ++i) - if (threads[i]->is_available_to(thisThread) && ++slavesCnt <= maxThreadsPerSplitPoint) + for (size_t i = 0; i < Threads.size() && !Fake; ++i) + if (Threads[i].is_available_to(this) && ++slavesCnt <= Threads.maxThreadsPerSplitPoint) { - sp.slavesMask |= 1ULL << threads[i]->idx; - threads[i]->activeSplitPoint = &sp; - threads[i]->searching = true; // Slave leaves idle_loop() - threads[i]->notify_one(); // Could be sleeping + sp.slavesMask |= 1ULL << Threads[i].idx; + Threads[i].activeSplitPoint = &sp; + Threads[i].searching = true; // Slave leaves idle_loop() + Threads[i].notify_one(); // Could be sleeping } sp.mutex.unlock(); - mutex.unlock(); + Threads.mutex.unlock(); // Everything is set up. The master thread enters the idle loop, from which // it will instantly launch a search, because its 'searching' flag is set. @@ -312,34 +310,34 @@ Value ThreadPool::split(Position& pos, Stack* ss, Value alpha, Value beta, // their work at this split point. if (slavesCnt > 1 || Fake) { - thisThread->Thread::idle_loop(); // Force a call to base class idle_loop() + Thread::idle_loop(); // Force a call to base class idle_loop() // 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(!thisThread->searching); + assert(!searching); } // We have returned from the idle loop, which means that all threads are // finished. Note that setting 'searching' and decreasing splitPointsSize is // done under lock protection to avoid a race with Thread::is_available_to(). - mutex.lock(); + Threads.mutex.lock(); sp.mutex.lock(); - thisThread->searching = true; - thisThread->splitPointsSize--; - thisThread->activeSplitPoint = sp.parentSplitPoint; + searching = true; + splitPointsSize--; + activeSplitPoint = sp.parentSplitPoint; pos.set_nodes_searched(pos.nodes_searched() + sp.nodes); *bestMove = sp.bestMove; sp.mutex.unlock(); - mutex.unlock(); + Threads.mutex.unlock(); return sp.bestValue; } // Explicit template instantiations -template Value ThreadPool::split(Position&, Stack*, Value, Value, Value, Move*, Depth, Move, int, MovePicker&, int); -template Value ThreadPool::split(Position&, Stack*, Value, Value, Value, Move*, Depth, Move, int, MovePicker&, int); +template Value Thread::split(Position&, Stack*, Value, Value, Value, Move*, Depth, Move, int, MovePicker&, int); +template Value Thread::split(Position&, Stack*, Value, Value, Value, Move*, Depth, Move, int, MovePicker&, int); // wait_for_think_finished() waits for main thread to go to sleep then returns diff --git a/src/thread.h b/src/thread.h index d24b65dc..76a2d843 100644 --- a/src/thread.h +++ b/src/thread.h @@ -102,6 +102,10 @@ struct Thread { bool is_available_to(Thread* master) const; void wait_for(volatile const bool& b); + template + Value split(Position& pos, Search::Stack* ss, Value alpha, Value beta, Value bestValue, Move* bestMove, + Depth depth, Move threatMove, int moveCount, MovePicker& mp, int nodeType); + SplitPoint splitPoints[MAX_SPLITPOINTS_PER_THREAD]; Material::Table materialTable; Endgames endgames; @@ -155,19 +159,15 @@ public: void start_thinking(const Position&, const Search::LimitsType&, const std::vector&, Search::StateStackPtr&); - template - Value split(Position& pos, Search::Stack* ss, Value alpha, Value beta, Value bestValue, Move* bestMove, - Depth depth, Move threatMove, int moveCount, MovePicker& mp, int nodeType); - bool sleepWhileIdle; Depth minimumSplitDepth; + size_t maxThreadsPerSplitPoint; Mutex mutex; ConditionVariable sleepCondition; private: std::vector threads; TimerThread* timer; - size_t maxThreadsPerSplitPoint; }; extern ThreadPool Threads; -- 2.39.2