mirror of
https://github.com/sockspls/badfish
synced 2025-07-12 03:59:15 +00:00
Retire RootNode template
There is no reason to compile 3 different copies of search(). PV nodes are on the cold path, and PvNode is a template parameter, so there is no cost in computing: const bool RootNode = PvNode && (ss-1)->ply == 0; And this simplifies code a tiny bit as well. Speed impact is negligible on my machine (i7-3770k, linux 4.2, gcc 5.2): nps +/- test 2378605 3118 master 2383128 2793 diff -4523 2746 Bench: 7751425 No functional change. Resolves #568
This commit is contained in:
parent
12eb345ebd
commit
28933a580e
1 changed files with 17 additions and 18 deletions
|
@ -62,7 +62,7 @@ using namespace Search;
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Different node types, used as a template parameter
|
// Different node types, used as a template parameter
|
||||||
enum NodeType { Root, PV, NonPV };
|
enum NodeType { NonPV, PV };
|
||||||
|
|
||||||
// Razoring and futility margin based on depth
|
// Razoring and futility margin based on depth
|
||||||
const int razor_margin[4] = { 483, 570, 603, 554 };
|
const int razor_margin[4] = { 483, 570, 603, 554 };
|
||||||
|
@ -441,7 +441,7 @@ void Thread::search() {
|
||||||
// high/low anymore.
|
// high/low anymore.
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
bestValue = ::search<Root>(rootPos, ss, alpha, beta, rootDepth, false);
|
bestValue = ::search<PV>(rootPos, ss, alpha, beta, rootDepth, false);
|
||||||
|
|
||||||
// Bring the best move to the front. It is critical that sorting
|
// Bring the best move to the front. It is critical that sorting
|
||||||
// is done with a stable algorithm because all the values but the
|
// is done with a stable algorithm because all the values but the
|
||||||
|
@ -589,8 +589,8 @@ namespace {
|
||||||
template <NodeType NT>
|
template <NodeType NT>
|
||||||
Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode) {
|
Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode) {
|
||||||
|
|
||||||
const bool RootNode = NT == Root;
|
const bool PvNode = NT == PV;
|
||||||
const bool PvNode = NT == PV || NT == Root;
|
const bool rootNode = PvNode && (ss-1)->ply == 0;
|
||||||
|
|
||||||
assert(-VALUE_INFINITE <= alpha && alpha < beta && beta <= VALUE_INFINITE);
|
assert(-VALUE_INFINITE <= alpha && alpha < beta && beta <= VALUE_INFINITE);
|
||||||
assert(PvNode || (alpha == beta - 1));
|
assert(PvNode || (alpha == beta - 1));
|
||||||
|
@ -632,7 +632,7 @@ namespace {
|
||||||
if (PvNode && thisThread->maxPly < ss->ply)
|
if (PvNode && thisThread->maxPly < ss->ply)
|
||||||
thisThread->maxPly = ss->ply;
|
thisThread->maxPly = ss->ply;
|
||||||
|
|
||||||
if (!RootNode)
|
if (!rootNode)
|
||||||
{
|
{
|
||||||
// Step 2. Check for aborted search and immediate draw
|
// Step 2. Check for aborted search and immediate draw
|
||||||
if (Signals.stop.load(std::memory_order_relaxed) || pos.is_draw() || ss->ply >= MAX_PLY)
|
if (Signals.stop.load(std::memory_order_relaxed) || pos.is_draw() || ss->ply >= MAX_PLY)
|
||||||
|
@ -664,7 +664,7 @@ namespace {
|
||||||
posKey = excludedMove ? pos.exclusion_key() : pos.key();
|
posKey = excludedMove ? pos.exclusion_key() : pos.key();
|
||||||
tte = TT.probe(posKey, ttHit);
|
tte = TT.probe(posKey, ttHit);
|
||||||
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
|
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
|
||||||
ttMove = RootNode ? thisThread->rootMoves[thisThread->PVIdx].pv[0]
|
ttMove = rootNode ? thisThread->rootMoves[thisThread->PVIdx].pv[0]
|
||||||
: ttHit ? tte->move() : MOVE_NONE;
|
: ttHit ? tte->move() : MOVE_NONE;
|
||||||
|
|
||||||
// At non-PV nodes we check for an early TT cutoff
|
// At non-PV nodes we check for an early TT cutoff
|
||||||
|
@ -685,7 +685,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4a. Tablebase probe
|
// Step 4a. Tablebase probe
|
||||||
if (!RootNode && TB::Cardinality)
|
if (!rootNode && TB::Cardinality)
|
||||||
{
|
{
|
||||||
int piecesCnt = pos.count<ALL_PIECES>(WHITE) + pos.count<ALL_PIECES>(BLACK);
|
int piecesCnt = pos.count<ALL_PIECES>(WHITE) + pos.count<ALL_PIECES>(BLACK);
|
||||||
|
|
||||||
|
@ -762,7 +762,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 7. Futility pruning: child node (skipped when in check)
|
// Step 7. Futility pruning: child node (skipped when in check)
|
||||||
if ( !RootNode
|
if ( !rootNode
|
||||||
&& depth < 7 * ONE_PLY
|
&& depth < 7 * ONE_PLY
|
||||||
&& eval - futility_margin(depth) >= beta
|
&& eval - futility_margin(depth) >= beta
|
||||||
&& eval < VALUE_KNOWN_WIN // Do not return unproven wins
|
&& eval < VALUE_KNOWN_WIN // Do not return unproven wins
|
||||||
|
@ -846,7 +846,7 @@ namespace {
|
||||||
{
|
{
|
||||||
Depth d = depth - 2 * ONE_PLY - (PvNode ? DEPTH_ZERO : depth / 4);
|
Depth d = depth - 2 * ONE_PLY - (PvNode ? DEPTH_ZERO : depth / 4);
|
||||||
ss->skipEarlyPruning = true;
|
ss->skipEarlyPruning = true;
|
||||||
search<PvNode ? PV : NonPV>(pos, ss, alpha, beta, d, true);
|
search<NT>(pos, ss, alpha, beta, d, true);
|
||||||
ss->skipEarlyPruning = false;
|
ss->skipEarlyPruning = false;
|
||||||
|
|
||||||
tte = TT.probe(posKey, ttHit);
|
tte = TT.probe(posKey, ttHit);
|
||||||
|
@ -866,7 +866,7 @@ moves_loop: // When in check search starts from here
|
||||||
|| ss->staticEval == VALUE_NONE
|
|| ss->staticEval == VALUE_NONE
|
||||||
||(ss-2)->staticEval == VALUE_NONE;
|
||(ss-2)->staticEval == VALUE_NONE;
|
||||||
|
|
||||||
singularExtensionNode = !RootNode
|
singularExtensionNode = !rootNode
|
||||||
&& depth >= 8 * ONE_PLY
|
&& depth >= 8 * ONE_PLY
|
||||||
&& ttMove != MOVE_NONE
|
&& ttMove != MOVE_NONE
|
||||||
/* && ttValue != VALUE_NONE Already implicit in the next condition */
|
/* && ttValue != VALUE_NONE Already implicit in the next condition */
|
||||||
|
@ -887,13 +887,13 @@ moves_loop: // When in check search starts from here
|
||||||
// At root obey the "searchmoves" option and skip moves not listed in Root
|
// At root obey the "searchmoves" option and skip moves not listed in Root
|
||||||
// Move List. As a consequence any illegal move is also skipped. In MultiPV
|
// Move List. As a consequence any illegal move is also skipped. In MultiPV
|
||||||
// mode we also skip PV moves which have been already searched.
|
// mode we also skip PV moves which have been already searched.
|
||||||
if (RootNode && !std::count(thisThread->rootMoves.begin() + thisThread->PVIdx,
|
if (rootNode && !std::count(thisThread->rootMoves.begin() + thisThread->PVIdx,
|
||||||
thisThread->rootMoves.end(), move))
|
thisThread->rootMoves.end(), move))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ss->moveCount = ++moveCount;
|
ss->moveCount = ++moveCount;
|
||||||
|
|
||||||
if (RootNode && thisThread == Threads.main() && Time.elapsed() > 3000)
|
if (rootNode && thisThread == Threads.main() && Time.elapsed() > 3000)
|
||||||
sync_cout << "info depth " << depth / ONE_PLY
|
sync_cout << "info depth " << depth / ONE_PLY
|
||||||
<< " currmove " << UCI::move(move, pos.is_chess960())
|
<< " currmove " << UCI::move(move, pos.is_chess960())
|
||||||
<< " currmovenumber " << moveCount + thisThread->PVIdx << sync_endl;
|
<< " currmovenumber " << moveCount + thisThread->PVIdx << sync_endl;
|
||||||
|
@ -937,7 +937,7 @@ moves_loop: // When in check search starts from here
|
||||||
newDepth = depth - ONE_PLY + extension;
|
newDepth = depth - ONE_PLY + extension;
|
||||||
|
|
||||||
// Step 13. Pruning at shallow depth
|
// Step 13. Pruning at shallow depth
|
||||||
if ( !RootNode
|
if ( !rootNode
|
||||||
&& !captureOrPromotion
|
&& !captureOrPromotion
|
||||||
&& !inCheck
|
&& !inCheck
|
||||||
&& !givesCheck
|
&& !givesCheck
|
||||||
|
@ -979,7 +979,7 @@ moves_loop: // When in check search starts from here
|
||||||
prefetch(TT.first_entry(pos.key_after(move)));
|
prefetch(TT.first_entry(pos.key_after(move)));
|
||||||
|
|
||||||
// Check for legality just before making the move
|
// Check for legality just before making the move
|
||||||
if (!RootNode && !pos.legal(move, ci.pinned))
|
if (!rootNode && !pos.legal(move, ci.pinned))
|
||||||
{
|
{
|
||||||
ss->moveCount = --moveCount;
|
ss->moveCount = --moveCount;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1038,7 +1038,7 @@ moves_loop: // When in check search starts from here
|
||||||
// For PV nodes only, do a full PV search on the first move or after a fail
|
// For PV nodes only, do a full PV search on the first move or after a fail
|
||||||
// high (in the latter case search only if value < beta), otherwise let the
|
// high (in the latter case search only if value < beta), otherwise let the
|
||||||
// parent node fail low with value <= alpha and try another move.
|
// parent node fail low with value <= alpha and try another move.
|
||||||
if (PvNode && (moveCount == 1 || (value > alpha && (RootNode || value < beta))))
|
if (PvNode && (moveCount == 1 || (value > alpha && (rootNode || value < beta))))
|
||||||
{
|
{
|
||||||
(ss+1)->pv = pv;
|
(ss+1)->pv = pv;
|
||||||
(ss+1)->pv[0] = MOVE_NONE;
|
(ss+1)->pv[0] = MOVE_NONE;
|
||||||
|
@ -1061,7 +1061,7 @@ moves_loop: // When in check search starts from here
|
||||||
if (Signals.stop.load(std::memory_order_relaxed))
|
if (Signals.stop.load(std::memory_order_relaxed))
|
||||||
return VALUE_ZERO;
|
return VALUE_ZERO;
|
||||||
|
|
||||||
if (RootNode)
|
if (rootNode)
|
||||||
{
|
{
|
||||||
RootMove& rm = *std::find(thisThread->rootMoves.begin(),
|
RootMove& rm = *std::find(thisThread->rootMoves.begin(),
|
||||||
thisThread->rootMoves.end(), move);
|
thisThread->rootMoves.end(), move);
|
||||||
|
@ -1105,7 +1105,7 @@ moves_loop: // When in check search starts from here
|
||||||
|
|
||||||
bestMove = move;
|
bestMove = move;
|
||||||
|
|
||||||
if (PvNode && !RootNode) // Update pv even in fail-high case
|
if (PvNode && !rootNode) // Update pv even in fail-high case
|
||||||
update_pv(ss->pv, move, (ss+1)->pv);
|
update_pv(ss->pv, move, (ss+1)->pv);
|
||||||
|
|
||||||
if (PvNode && value < beta) // Update alpha! Always alpha < beta
|
if (PvNode && value < beta) // Update alpha! Always alpha < beta
|
||||||
|
@ -1176,7 +1176,6 @@ moves_loop: // When in check search starts from here
|
||||||
|
|
||||||
const bool PvNode = NT == PV;
|
const bool PvNode = NT == PV;
|
||||||
|
|
||||||
assert(NT == PV || NT == NonPV);
|
|
||||||
assert(InCheck == !!pos.checkers());
|
assert(InCheck == !!pos.checkers());
|
||||||
assert(alpha >= -VALUE_INFINITE && alpha < beta && beta <= VALUE_INFINITE);
|
assert(alpha >= -VALUE_INFINITE && alpha < beta && beta <= VALUE_INFINITE);
|
||||||
assert(PvNode || (alpha == beta - 1));
|
assert(PvNode || (alpha == beta - 1));
|
||||||
|
|
Loading…
Add table
Reference in a new issue