Move best = MOVE_NONE;
};
- // Breadcrumbs are used to mark nodes as being searched by a given thread
- struct Breadcrumb {
- std::atomic<Thread*> thread;
- std::atomic<Key> key;
- };
- std::array<Breadcrumb, 1024> breadcrumbs;
-
- // ThreadHolding structure keeps track of which thread left breadcrumbs at the given
- // node for potential reductions. A free node will be marked upon entering the moves
- // loop by the constructor, and unmarked upon leaving that loop by the destructor.
- struct ThreadHolding {
- explicit ThreadHolding(Thread* thisThread, Key posKey, int ply) {
- location = ply < 8 ? &breadcrumbs[posKey & (breadcrumbs.size() - 1)] : nullptr;
- otherThread = false;
- owning = false;
- if (location)
- {
- // See if another already marked this location, if not, mark it ourselves
- Thread* tmp = (*location).thread.load(std::memory_order_relaxed);
- if (tmp == nullptr)
- {
- (*location).thread.store(thisThread, std::memory_order_relaxed);
- (*location).key.store(posKey, std::memory_order_relaxed);
- owning = true;
- }
- else if ( tmp != thisThread
- && (*location).key.load(std::memory_order_relaxed) == posKey)
- otherThread = true;
- }
- }
-
- ~ThreadHolding() {
- if (owning) // Free the marked location
- (*location).thread.store(nullptr, std::memory_order_relaxed);
- }
-
- bool marked() { return otherThread; }
-
- private:
- Breadcrumb* location;
- bool otherThread, owning;
- };
-
template <NodeType NT>
Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode);
&& (tte->bound() & BOUND_UPPER)
&& tte->depth() >= depth;
- // Mark this node as being searched
- ThreadHolding th(thisThread, posKey, ss->ply);
-
// Step 12. Loop through all pseudo-legal moves until no moves remain
// or a beta cutoff occurs.
while ((move = mp.next_move(moveCountPruning)) != MOVE_NONE)
if (thisThread->ttHitAverage > 537 * TtHitAverageResolution * TtHitAverageWindow / 1024)
r--;
- // Increase reduction if other threads are searching this position
- if (th.marked())
- r++;
-
// Decrease reduction if position is or has been on the PV
// and node is not likely to fail low. (~10 Elo)
if ( ss->ttPv
&& thisThread->bestMoveChanges <= 2)
r++;
- // Decrease reduction if opponent's move count is high (~5 Elo)
+ // Decrease reduction if opponent's move count is high (~1 Elo)
if ((ss-1)->moveCount > 13)
r--;
if (singularQuietLMR)
r--;
- if (captureOrPromotion)
- {
- // Increase reduction for non-checking captures likely to be bad
- if ( !givesCheck
- && ss->staticEval + PieceValue[EG][pos.captured_piece()] + 210 * depth <= alpha)
- r++;
- }
- else
+ if (!captureOrPromotion)
{
// Increase reduction if ttMove is a capture (~3 Elo)
if (ttCapture)