Skip to content

Commit

Permalink
Simplify Step 9 by replacing (depth - R) with an almost ecquivalent.
Browse files Browse the repository at this point in the history
While being there remove also all pointless thisThread-> references
(=cosmetics).

bench: 2226664
  • Loading branch information
pb00067 committed Apr 2, 2024
1 parent 0716b84 commit 6f5d06b
Showing 1 changed file with 53 additions and 54 deletions.
107 changes: 53 additions & 54 deletions src/search.cpp
Expand Up @@ -559,17 +559,17 @@ Value Search::Worker::search(
main_manager()->check_time(*thisThread);

// Used to send selDepth info to GUI (selDepth counts from 1, ply from 0)
if (PvNode && thisThread->selDepth < ss->ply + 1)
thisThread->selDepth = ss->ply + 1;
if (PvNode && selDepth < ss->ply + 1)
selDepth = ss->ply + 1;

if (!rootNode)
{
// Step 2. Check for aborted search and immediate draw
if (threads.stop.load(std::memory_order_relaxed) || pos.is_draw(ss->ply)
|| ss->ply >= MAX_PLY)
return (ss->ply >= MAX_PLY && !ss->inCheck)
? evaluate(networks, pos, thisThread->optimism[us])
: value_draw(thisThread->nodes);
? evaluate(networks, pos, optimism[us])
: value_draw(nodes);

// Step 3. Mate distance pruning. Even if we mate at the next move our score
// would be at best mate_in(ss->ply + 1), but if alpha is already bigger because
Expand All @@ -583,7 +583,7 @@ Value Search::Worker::search(
return alpha;
}
else
thisThread->rootDelta = beta - alpha;
rootDelta = beta - alpha;

assert(0 <= ss->ply && ss->ply < MAX_PLY);

Expand All @@ -599,7 +599,7 @@ Value Search::Worker::search(
posKey = pos.key();
tte = tt.probe(posKey, ss->ttHit);
ttValue = ss->ttHit ? value_from_tt(tte->value(), ss->ply, pos.rule50_count()) : VALUE_NONE;
ttMove = rootNode ? thisThread->rootMoves[thisThread->pvIdx].pv[0]
ttMove = rootNode ? rootMoves[pvIdx].pv[0]
: ss->ttHit ? tte->move()
: Move::none();
ttCapture = ttMove && pos.capture_stage(ttMove);
Expand Down Expand Up @@ -654,7 +654,7 @@ Value Search::Worker::search(

if (err != TB::ProbeState::FAIL)
{
thisThread->tbHits.fetch_add(1, std::memory_order_relaxed);
tbHits.fetch_add(1, std::memory_order_relaxed);

int drawScore = tbConfig.useRule50 ? 1 : 0;

Expand Down Expand Up @@ -710,7 +710,7 @@ Value Search::Worker::search(
// Never assume anything about values stored in TT
unadjustedStaticEval = tte->eval();
if (unadjustedStaticEval == VALUE_NONE)
unadjustedStaticEval = evaluate(networks, pos, thisThread->optimism[us]);
unadjustedStaticEval = evaluate(networks, pos, optimism[us]);
else if (PvNode)
Eval::NNUE::hint_common_parent_position(pos, networks);

Expand All @@ -722,7 +722,7 @@ Value Search::Worker::search(
}
else
{
unadjustedStaticEval = evaluate(networks, pos, thisThread->optimism[us]);
unadjustedStaticEval = evaluate(networks, pos, optimism[us]);
ss->staticEval = eval = to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos);

// Static evaluation is saved as it was before adjustment by correction history
Expand All @@ -735,9 +735,9 @@ Value Search::Worker::search(
{
int bonus = std::clamp(-13 * int((ss - 1)->staticEval + ss->staticEval), -1578, 1291);
bonus = bonus > 0 ? 2 * bonus : bonus / 2;
thisThread->mainHistory[~us][((ss - 1)->currentMove).from_to()] << bonus;
mainHistory[~us][((ss - 1)->currentMove).from_to()] << bonus;
if (type_of(pos.piece_on(prevSq)) != PAWN && ((ss - 1)->currentMove).type_of() != PROMOTION)
thisThread->pawnHistory[pawn_structure_index(pos)][pos.piece_on(prevSq)][prevSq]
pawnHistory[pawn_structure_index(pos)][pos.piece_on(prevSq)][prevSq]
<< bonus / 2;
}

Expand Down Expand Up @@ -775,38 +775,37 @@ Value Search::Worker::search(
// Step 9. Null move search with verification search (~35 Elo)
if (!PvNode && (ss - 1)->currentMove != Move::null() && (ss - 1)->statScore < 16878
&& eval >= beta && ss->staticEval >= beta - 20 * depth + 314 && !excludedMove
&& pos.non_pawn_material(us) && ss->ply >= thisThread->nmpMinPly
&& pos.non_pawn_material(us) && ss->ply >= nmpMinPly
&& beta > VALUE_TB_LOSS_IN_MAX_PLY)
{
assert(eval - beta >= 0);

// Null move dynamic reduction based on depth and eval
Depth R = std::min(int(eval - beta) / 144, 6) + depth / 3 + 4;

// Null move dynamic depth based on eval and actual depth
Depth nmDepth = 2 * depth / 3 - std::min(int(eval - beta) / 144, 6) - 4;
ss->currentMove = Move::null();
ss->continuationHistory = &thisThread->continuationHistory[0][0][NO_PIECE][0];
ss->continuationHistory = &continuationHistory[0][0][NO_PIECE][0];

pos.do_null_move(st, tt);

Value nullValue = -search<NonPV>(pos, ss + 1, -beta, -beta + 1, depth - R, !cutNode);
Value nullValue = -search<NonPV>(pos, ss + 1, -beta, -beta + 1, nmDepth, !cutNode);

pos.undo_null_move();

// Do not return unproven mate or TB scores
if (nullValue >= beta && nullValue < VALUE_TB_WIN_IN_MAX_PLY)
{
if (thisThread->nmpMinPly || depth < 16)
if (nmpMinPly || depth < 16)
return nullValue;

assert(!thisThread->nmpMinPly); // Recursive verification is not allowed
assert(!nmpMinPly); // Recursive verification is not allowed

// Do verification search at high depths, with null move pruning disabled
// until ply exceeds nmpMinPly.
thisThread->nmpMinPly = ss->ply + 3 * (depth - R) / 4;
nmpMinPly = ss->ply + 3 * nmDepth / 4;

Value v = search<NonPV>(pos, ss, beta - 1, beta, depth - R, false);
Value v = search<NonPV>(pos, ss, beta - 1, beta, nmDepth, false);

thisThread->nmpMinPly = 0;
nmpMinPly = 0;

if (v >= beta)
return nullValue;
Expand Down Expand Up @@ -841,7 +840,7 @@ Value Search::Worker::search(
{
assert(probCutBeta < VALUE_INFINITE && probCutBeta > beta);

MovePicker mp(pos, ttMove, probCutBeta - ss->staticEval, &thisThread->captureHistory);
MovePicker mp(pos, ttMove, probCutBeta - ss->staticEval, &captureHistory);

while ((move = mp.next_move()) != Move::none())
if (move != excludedMove && pos.legal(move))
Expand All @@ -856,7 +855,7 @@ Value Search::Worker::search(
&this
->continuationHistory[ss->inCheck][true][pos.moved_piece(move)][move.to_sq()];

thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
nodes.fetch_add(1, std::memory_order_relaxed);
pos.do_move(move, st);

// Perform a preliminary qsearch to verify that the move holds
Expand Down Expand Up @@ -899,10 +898,10 @@ Value Search::Worker::search(
(ss - 6)->continuationHistory};

Move countermove =
prevSq != SQ_NONE ? thisThread->counterMoves[pos.piece_on(prevSq)][prevSq] : Move::none();
prevSq != SQ_NONE ? counterMoves[pos.piece_on(prevSq)][prevSq] : Move::none();

MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory, &thisThread->captureHistory,
contHist, &thisThread->pawnHistory, countermove, ss->killers);
MovePicker mp(pos, ttMove, depth, &mainHistory, &captureHistory,
contHist, &pawnHistory, countermove, ss->killers);

value = bestValue;
moveCountPruning = false;
Expand All @@ -924,8 +923,8 @@ Value Search::Worker::search(
// Move List. In MultiPV mode we also skip PV moves that have been already
// searched and those of lower "TB rank" if we are in a TB root position.
if (rootNode
&& !std::count(thisThread->rootMoves.begin() + thisThread->pvIdx,
thisThread->rootMoves.begin() + thisThread->pvLast, move))
&& !std::count(rootMoves.begin() + pvIdx,
rootMoves.begin() + pvLast, move))
continue;

ss->moveCount = ++moveCount;
Expand All @@ -934,7 +933,7 @@ Value Search::Worker::search(
&& main_manager()->tm.elapsed(threads.nodes_searched()) > 3000)
sync_cout << "info depth " << depth << " currmove "
<< UCI::move(move, pos.is_chess960()) << " currmovenumber "
<< moveCount + thisThread->pvIdx << sync_endl;
<< moveCount + pvIdx << sync_endl;
if (PvNode)
(ss + 1)->pv = nullptr;

Expand Down Expand Up @@ -969,7 +968,7 @@ Value Search::Worker::search(
Piece capturedPiece = pos.piece_on(move.to_sq());
int futilityEval =
ss->staticEval + 297 + 284 * lmrDepth + PieceValue[capturedPiece]
+ thisThread->captureHistory[movedPiece][move.to_sq()][type_of(capturedPiece)]
+ captureHistory[movedPiece][move.to_sq()][type_of(capturedPiece)]
/ 7;
if (futilityEval < alpha)
continue;
Expand All @@ -985,13 +984,13 @@ Value Search::Worker::search(
(*contHist[0])[movedPiece][move.to_sq()]
+ (*contHist[1])[movedPiece][move.to_sq()]
+ (*contHist[3])[movedPiece][move.to_sq()]
+ thisThread->pawnHistory[pawn_structure_index(pos)][movedPiece][move.to_sq()];
+ pawnHistory[pawn_structure_index(pos)][movedPiece][move.to_sq()];

// Continuation history based pruning (~2 Elo)
if (lmrDepth < 6 && history < -4040 * depth)
continue;

history += 2 * thisThread->mainHistory[us][move.from_to()];
history += 2 * mainHistory[us][move.from_to()];

lmrDepth += history / 5637;

Expand All @@ -1017,7 +1016,7 @@ Value Search::Worker::search(

// Step 15. Extensions (~100 Elo)
// We take care to not overdo to avoid search getting stuck.
if (ss->ply < thisThread->rootDepth * 2)
if (ss->ply < rootDepth * 2)
{
// Singular extension search (~94 Elo). If all moves but one fail low on a
// search of (alpha-s, beta-s), and just one fails high on (alpha, beta),
Expand All @@ -1030,7 +1029,7 @@ Value Search::Worker::search(
// so changing them requires tests at these types of time controls.
// Recursive singular search is avoided.
if (!rootNode && move == ttMove && !excludedMove
&& depth >= 4 - (thisThread->completedDepth > 30) + ss->ttPv
&& depth >= 4 - (completedDepth > 30) + ss->ttPv
&& std::abs(ttValue) < VALUE_TB_WIN_IN_MAX_PLY && (tte->bound() & BOUND_LOWER)
&& tte->depth() >= depth - 3)
{
Expand Down Expand Up @@ -1086,7 +1085,7 @@ Value Search::Worker::search(

// Recapture extensions (~0 Elo on STC, ~1 Elo on LTC)
else if (PvNode && move == ttMove && move.to_sq() == prevSq
&& thisThread->captureHistory[movedPiece][move.to_sq()]
&& captureHistory[movedPiece][move.to_sq()]
[type_of(pos.piece_on(move.to_sq()))]
> 4026)
extension = 1;
Expand All @@ -1102,12 +1101,12 @@ Value Search::Worker::search(
// Update the current move (this must be done after singular extension search)
ss->currentMove = move;
ss->continuationHistory =
&thisThread->continuationHistory[ss->inCheck][capture][movedPiece][move.to_sq()];
&continuationHistory[ss->inCheck][capture][movedPiece][move.to_sq()];

uint64_t nodeCount = rootNode ? uint64_t(nodes) : 0;

// Step 16. Make the move
thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
nodes.fetch_add(1, std::memory_order_relaxed);
pos.do_move(move, st, givesCheck);

// Decrease reduction if position is or has been on the PV (~7 Elo)
Expand Down Expand Up @@ -1135,7 +1134,7 @@ Value Search::Worker::search(
else if (move == ttMove)
r = 0;

ss->statScore = 2 * thisThread->mainHistory[us][move.from_to()]
ss->statScore = 2 * mainHistory[us][move.from_to()]
+ (*contHist[0])[movedPiece][move.to_sq()]
+ (*contHist[1])[movedPiece][move.to_sq()]
+ (*contHist[3])[movedPiece][move.to_sq()] - 4723;
Expand Down Expand Up @@ -1213,7 +1212,7 @@ Value Search::Worker::search(
if (rootNode)
{
RootMove& rm =
*std::find(thisThread->rootMoves.begin(), thisThread->rootMoves.end(), move);
*std::find(rootMoves.begin(), rootMoves.end(), move);

rm.effort += nodes - nodeCount;

Expand All @@ -1224,7 +1223,7 @@ Value Search::Worker::search(
if (moveCount == 1 || value > alpha)
{
rm.score = rm.uciScore = value;
rm.selDepth = thisThread->selDepth;
rm.selDepth = selDepth;
rm.scoreLowerbound = rm.scoreUpperbound = false;

if (value >= beta)
Expand All @@ -1248,8 +1247,8 @@ Value Search::Worker::search(
// We record how often the best move has been changed in each iteration.
// This information is used for time management. In MultiPV mode,
// we must take care to only do this for the first PV line.
if (moveCount > 1 && !thisThread->pvIdx)
++thisThread->bestMoveChanges;
if (moveCount > 1 && !pvIdx)
++bestMoveChanges;
}
else
// All other moves but the PV, are set to the lowest value: this
Expand Down Expand Up @@ -1326,7 +1325,7 @@ Value Search::Worker::search(
+ (!ss->inCheck && bestValue <= ss->staticEval - 150);
update_continuation_histories(ss - 1, pos.piece_on(prevSq), prevSq,
stat_bonus(depth) * bonus);
thisThread->mainHistory[~us][((ss - 1)->currentMove).from_to()]
mainHistory[~us][((ss - 1)->currentMove).from_to()]
<< stat_bonus(depth) * bonus / 2;
}

Expand All @@ -1340,7 +1339,7 @@ Value Search::Worker::search(

// Write gathered information in transposition table
// Static evaluation is saved as it was before correction history
if (!excludedMove && !(rootNode && thisThread->pvIdx))
if (!excludedMove && !(rootNode && pvIdx))
tte->save(posKey, value_to_tt(bestValue, ss->ply), ss->ttPv,
bestValue >= beta ? BOUND_LOWER
: PvNode && bestMove ? BOUND_EXACT
Expand All @@ -1354,7 +1353,7 @@ Value Search::Worker::search(
{
auto bonus = std::clamp(int(bestValue - ss->staticEval) * depth / 8,
-CORRECTION_HISTORY_LIMIT / 4, CORRECTION_HISTORY_LIMIT / 4);
thisThread->correctionHistory[us][pawn_structure_index<Correction>(pos)] << bonus;
correctionHistory[us][pawn_structure_index<Correction>(pos)] << bonus;
}

assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
Expand Down Expand Up @@ -1411,13 +1410,13 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta,
moveCount = 0;

// Used to send selDepth info to GUI (selDepth counts from 1, ply from 0)
if (PvNode && thisThread->selDepth < ss->ply + 1)
thisThread->selDepth = ss->ply + 1;
if (PvNode && selDepth < ss->ply + 1)
selDepth = ss->ply + 1;

// Step 2. Check for an immediate draw or maximum ply reached
if (pos.is_draw(ss->ply) || ss->ply >= MAX_PLY)
return (ss->ply >= MAX_PLY && !ss->inCheck)
? evaluate(networks, pos, thisThread->optimism[us])
? evaluate(networks, pos, optimism[us])
: VALUE_DRAW;

assert(0 <= ss->ply && ss->ply < MAX_PLY);
Expand Down Expand Up @@ -1449,7 +1448,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta,
// Never assume anything about values stored in TT
unadjustedStaticEval = tte->eval();
if (unadjustedStaticEval == VALUE_NONE)
unadjustedStaticEval = evaluate(networks, pos, thisThread->optimism[us]);
unadjustedStaticEval = evaluate(networks, pos, optimism[us]);
ss->staticEval = bestValue =
to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos);

Expand All @@ -1462,7 +1461,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta,
{
// In case of null move search, use previous static eval with a different sign
unadjustedStaticEval = (ss - 1)->currentMove != Move::null()
? evaluate(networks, pos, thisThread->optimism[us])
? evaluate(networks, pos, optimism[us])
: -(ss - 1)->staticEval;
ss->staticEval = bestValue =
to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos);
Expand Down Expand Up @@ -1492,8 +1491,8 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta,
// queen promotions, and other checks (only if depth >= DEPTH_QS_CHECKS)
// will be generated.
Square prevSq = ((ss - 1)->currentMove).is_ok() ? ((ss - 1)->currentMove).to_sq() : SQ_NONE;
MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory, &thisThread->captureHistory,
contHist, &thisThread->pawnHistory);
MovePicker mp(pos, ttMove, depth, &mainHistory, &captureHistory,
contHist, &pawnHistory);

int quietCheckEvasions = 0;

Expand Down Expand Up @@ -1577,7 +1576,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta,
quietCheckEvasions += !capture && ss->inCheck;

// Step 7. Make and search the move
thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
nodes.fetch_add(1, std::memory_order_relaxed);
pos.do_move(move, st, givesCheck);
value = -qsearch<nodeType>(pos, ss + 1, -beta, -alpha, depth - 1);
pos.undo_move(move);
Expand Down

2 comments on commit 6f5d06b

@Disservin
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding thisThread see
official-stockfish#4968

For consistency with the old search code, thisThread has been kept, even though it is not strictly necessary anymore.

was also discussed on discord

@pb00068
Copy link
Owner

@pb00068 pb00068 commented on 6f5d06b Apr 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Disservin . Did'nt know that.

Please sign in to comment.