X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=a6f4d6bdd462d13a2472b8abd444f9b17881c554;hp=04d67afebf77195f15f8e85758d488ef17fed5d9;hb=0b36ba74fc0a80388cac43a35962ffc73c01b071;hpb=40548c9153ea89c0b27b198efb443c5bb9b9c490 diff --git a/src/search.cpp b/src/search.cpp index 04d67afe..a6f4d6bd 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -41,7 +41,7 @@ namespace Search { LimitsType Limits; RootMoveVector RootMoves; Position RootPos; - Time::point SearchTime; + TimePoint SearchTime; StateStackPtr SetupStates; } @@ -355,7 +355,7 @@ namespace { // the UI) before a re-search. if ( multiPV == 1 && (bestValue <= alpha || bestValue >= beta) - && Time::now() - SearchTime > 3000) + && now() - SearchTime > 3000) sync_cout << UCI::pv(pos, depth, alpha, beta) << sync_endl; // In case of failing low/high increase aspiration window and @@ -386,9 +386,9 @@ namespace { if (Signals.stop) sync_cout << "info nodes " << RootPos.nodes_searched() - << " time " << Time::now() - SearchTime << sync_endl; + << " time " << now() - SearchTime << sync_endl; - else if (PVIdx + 1 == multiPV || Time::now() - SearchTime > 3000) + else if (PVIdx + 1 == multiPV || now() - SearchTime > 3000) sync_cout << UCI::pv(pos, depth, alpha, beta) << sync_endl; } @@ -412,7 +412,7 @@ namespace { // Stop the search if only one legal move is available or all // of the available time has been used. if ( RootMoves.size() == 1 - || Time::now() - SearchTime > TimeMgr.available_time()) + || now() - SearchTime > TimeMgr.available_time()) { // If we are allowed to ponder do not stop the search now but // keep pondering until the GUI sends "ponderhit" or "stop". @@ -765,7 +765,7 @@ moves_loop: // When in check and at SpNode search starts from here continue; moveCount = ++splitPoint->moveCount; - splitPoint->mutex.unlock(); + splitPoint->spinlock.release(); } else ++moveCount; @@ -774,7 +774,7 @@ moves_loop: // When in check and at SpNode search starts from here { Signals.firstRootMove = (moveCount == 1); - if (thisThread == Threads.main() && Time::now() - SearchTime > 3000) + if (thisThread == Threads.main() && now() - SearchTime > 3000) sync_cout << "info depth " << depth / ONE_PLY << " currmove " << UCI::move(move, pos.is_chess960()) << " currmovenumber " << moveCount + PVIdx << sync_endl; @@ -834,7 +834,7 @@ moves_loop: // When in check and at SpNode search starts from here && moveCount >= FutilityMoveCounts[improving][depth]) { if (SpNode) - splitPoint->mutex.lock(); + splitPoint->spinlock.acquire(); continue; } @@ -853,7 +853,7 @@ moves_loop: // When in check and at SpNode search starts from here if (SpNode) { - splitPoint->mutex.lock(); + splitPoint->spinlock.acquire(); if (bestValue > splitPoint->bestValue) splitPoint->bestValue = bestValue; } @@ -865,7 +865,7 @@ moves_loop: // When in check and at SpNode search starts from here if (predictedDepth < 4 * ONE_PLY && pos.see_sign(move) < VALUE_ZERO) { if (SpNode) - splitPoint->mutex.lock(); + splitPoint->spinlock.acquire(); continue; } @@ -965,7 +965,7 @@ moves_loop: // When in check and at SpNode search starts from here // Step 18. Check for new best move if (SpNode) { - splitPoint->mutex.lock(); + splitPoint->spinlock.acquire(); bestValue = splitPoint->bestValue; alpha = splitPoint->alpha; } @@ -1373,7 +1373,7 @@ moves_loop: // When in check and at SpNode search starts from here Move Skill::pick_best(size_t multiPV) { // PRNG sequence should be non-deterministic, so we seed it with the time at init - static PRNG rng(Time::now()); + static PRNG rng(now()); // RootMoves are already sorted by score in descending order int variance = std::min(RootMoves[0].score - RootMoves[multiPV - 1].score, PawnValueMg); @@ -1407,7 +1407,7 @@ moves_loop: // When in check and at SpNode search starts from here string UCI::pv(const Position& pos, Depth depth, Value alpha, Value beta) { std::stringstream ss; - Time::point elapsed = Time::now() - SearchTime + 1; + TimePoint elapsed = now() - SearchTime + 1; size_t multiPV = std::min((size_t)Options["MultiPV"], RootMoves.size()); int selDepth = 0; @@ -1517,21 +1517,22 @@ void Thread::idle_loop() { // Pointer 'this_sp' is not null only if we are called from split(), and not // at the thread creation. This means we are the split point's master. - SplitPoint* this_sp = splitPointsSize ? activeSplitPoint : nullptr; + SplitPoint* this_sp = activeSplitPoint; - assert(!this_sp || (this_sp->masterThread == this && searching)); + assert(!this_sp || (this_sp->master == this && searching)); while (!exit) { // If this thread has been assigned work, launch a search while (searching) { - Threads.mutex.lock(); + Threads.spinlock.acquire(); assert(activeSplitPoint); + SplitPoint* sp = activeSplitPoint; - Threads.mutex.unlock(); + Threads.spinlock.release(); Stack stack[MAX_PLY+4], *ss = stack+2; // To allow referencing (ss-2) and (ss+2) Position pos(*sp->pos, this); @@ -1539,7 +1540,7 @@ void Thread::idle_loop() { std::memcpy(ss-2, sp->ss-2, 5 * sizeof(Stack)); ss->splitPoint = sp; - sp->mutex.lock(); + sp->spinlock.acquire(); assert(activePosition == nullptr); @@ -1567,51 +1568,47 @@ void Thread::idle_loop() { // Wake up the master thread so to allow it to return from the idle // loop in case we are the last slave of the split point. - if ( this != sp->masterThread - && sp->slavesMask.none()) + if (this != sp->master && sp->slavesMask.none()) { - assert(!sp->masterThread->searching); - sp->masterThread->notify_one(); + assert(!sp->master->searching); + + sp->master->notify_one(); } // After releasing the lock we can't access any SplitPoint related data // in a safe way because it could have been released under our feet by // the sp master. - sp->mutex.unlock(); + sp->spinlock.release(); // Try to late join to another split point if none of its slaves has // already finished. SplitPoint* bestSp = NULL; - Thread* bestThread = NULL; - int bestScore = INT_MAX; + int minLevel = INT_MAX; - for (size_t i = 0; i < Threads.size(); ++i) + for (Thread* th : Threads) { - const size_t size = Threads[i]->splitPointsSize; // Local copy - sp = size ? &Threads[i]->splitPoints[size - 1] : nullptr; + const size_t size = th->splitPointsSize; // Local copy + sp = size ? &th->splitPoints[size - 1] : nullptr; if ( sp && sp->allSlavesSearching && sp->slavesMask.count() < MAX_SLAVES_PER_SPLITPOINT - && available_to(Threads[i])) + && available_to(sp->master)) { - assert(this != Threads[i]); + assert(this != th); assert(!(this_sp && this_sp->slavesMask.none())); assert(Threads.size() > 2); // Prefer to join to SP with few parents to reduce the probability // that a cut-off occurs above us, and hence we waste our work. - int level = -1; - for (SplitPoint* spp = Threads[i]->activeSplitPoint; spp; spp = spp->parentSplitPoint) + int level = 0; + for (SplitPoint* p = th->activeSplitPoint; p; p = p->parentSplitPoint) level++; - int score = level * 256 * 256 + (int)sp->slavesMask.count() * 256 - sp->depth * 1; - - if (score < bestScore) + if (level < minLevel) { bestSp = sp; - bestThread = Threads[i]; - bestScore = score; + minLevel = level; } } } @@ -1621,24 +1618,24 @@ void Thread::idle_loop() { sp = bestSp; // Recheck the conditions under lock protection - Threads.mutex.lock(); - sp->mutex.lock(); + Threads.spinlock.acquire(); + sp->spinlock.acquire(); if ( sp->allSlavesSearching && sp->slavesMask.count() < MAX_SLAVES_PER_SPLITPOINT - && available_to(bestThread)) + && available_to(sp->master)) { sp->slavesMask.set(idx); activeSplitPoint = sp; searching = true; } - sp->mutex.unlock(); - Threads.mutex.unlock(); + sp->spinlock.release(); + Threads.spinlock.release(); } } - // Grab the lock to avoid races with Thread::notify_one() + // Avoid races with notify_one() fired from last slave of the split point std::unique_lock lk(mutex); // If we are master and all slaves have finished then exit idle_loop @@ -1662,12 +1659,12 @@ void Thread::idle_loop() { void check_time() { - static Time::point lastInfoTime = Time::now(); - Time::point elapsed = Time::now() - SearchTime; + static TimePoint lastInfoTime = now(); + TimePoint elapsed = now() - SearchTime; - if (Time::now() - lastInfoTime >= 1000) + if (now() - lastInfoTime >= 1000) { - lastInfoTime = Time::now(); + lastInfoTime = now(); dbg_print(); } @@ -1690,7 +1687,7 @@ void check_time() { else if (Limits.nodes) { - Threads.mutex.lock(); + Threads.spinlock.acquire(); int64_t nodes = RootPos.nodes_searched(); @@ -1701,7 +1698,7 @@ void check_time() { { SplitPoint& sp = th->splitPoints[i]; - sp.mutex.lock(); + sp.spinlock.acquire(); nodes += sp.nodes; @@ -1709,10 +1706,10 @@ void check_time() { if (sp.slavesMask.test(idx) && Threads[idx]->activePosition) nodes += Threads[idx]->activePosition->nodes_searched(); - sp.mutex.unlock(); + sp.spinlock.release(); } - Threads.mutex.unlock(); + Threads.spinlock.release(); if (nodes >= Limits.nodes) Signals.stop = true;