};
- /// Constants and variables initialized from UCI options
+ /// Constants
- // Minimum number of full depth (i.e. non-reduced) moves at PV and non-PV
- // nodes
- int LMRPVMoves, LMRNonPVMoves;
-
- // Depth limit for use of dynamic threat detection
- Depth ThreatDepth;
+ // Search depth at iteration 1
+ const Depth InitialDepth = OnePly /*+ OnePly/2*/;
// Depth limit for selective search
- const Depth SelectiveDepth = 7*OnePly;
+ const Depth SelectiveDepth = 7 * OnePly;
// Use internal iterative deepening?
const bool UseIIDAtPVNodes = true;
const bool PruneDefendingMoves = false;
const bool PruneBlockingMoves = false;
- // Use futility pruning?
- bool UseQSearchFutilityPruning, UseFutilityPruning;
-
// Margins for futility pruning in the quiescence search, and at frontier
// and near frontier nodes
const Value FutilityMarginQS = Value(0x80);
- // Remaining depth: 1 ply 1.5 ply 2 ply 2.5 ply 3 ply 3.5 ply
- const Value FutilityMargins[12] = { Value(0x100), Value(0x120), Value(0x200), Value(0x220), Value(0x250), Value(0x270),
+ // Remaining depth: 1 ply 1.5 ply 2 ply 2.5 ply 3 ply 3.5 ply
+ const Value FutilityMargins[12] = { Value(0x100), Value(0x120), Value(0x200), Value(0x220), Value(0x250), Value(0x270),
// 4 ply 4.5 ply 5 ply 5.5 ply 6 ply 6.5 ply
Value(0x2A0), Value(0x2C0), Value(0x340), Value(0x360), Value(0x3A0), Value(0x3C0) };
- // Razoring
- const Depth RazorDepth = 4*OnePly;
+ // Razoring
+ const Depth RazorDepth = 4*OnePly;
// Remaining depth: 1 ply 1.5 ply 2 ply 2.5 ply 3 ply 3.5 ply
const Value RazorMargins[6] = { Value(0x180), Value(0x300), Value(0x300), Value(0x3C0), Value(0x3C0), Value(0x3C0) };
// Remaining depth: 1 ply 1.5 ply 2 ply 2.5 ply 3 ply 3.5 ply
- const Value RazorApprMargins[6] = { Value(0x520), Value(0x300), Value(0x300), Value(0x300), Value(0x300), Value(0x300) };
+ const Value RazorApprMargins[6] = { Value(0x520), Value(0x300), Value(0x300), Value(0x300), Value(0x300), Value(0x300) };
+
+
+ /// Variables initialized from UCI options
+
+ // Minimum number of full depth (i.e. non-reduced) moves at PV and non-PV nodes
+ int LMRPVMoves, LMRNonPVMoves; // heavy SMP read access for the latter
+
+ // Depth limit for use of dynamic threat detection
+ Depth ThreatDepth; // heavy SMP read access
// Last seconds noise filtering (LSN)
bool UseLSNFiltering;
Value LSNValue;
// Extensions. Array index 0 is used at non-PV nodes, index 1 at PV nodes.
+ // There is heavy SMP read access on these arrays
Depth CheckExtension[2], SingleReplyExtension[2], PawnPushTo7thExtension[2];
Depth PassedPawnExtension[2], PawnEndgameExtension[2], MateThreatExtension[2];
- // Search depth at iteration 1
- const Depth InitialDepth = OnePly /*+ OnePly/2*/;
-
- // Node counters
- int NodesSincePoll;
- int NodesBetweenPolls = 30000;
-
// Iteration counters
int Iteration;
- BetaCounterType BetaCounter;
+ BetaCounterType BetaCounter; // has per-thread internal data
- // Scores and number of times the best move changed for each iteration:
+ // Scores and number of times the best move changed for each iteration
IterationInfoType IterationInfo[PLY_MAX_PLUS_2];
int BestMoveChangesByIteration[PLY_MAX_PLUS_2];
bool InfiniteSearch;
bool PonderSearch;
bool StopOnPonderhit;
- bool AbortSearch;
+ bool AbortSearch; // heavy SMP read access
bool Quit;
bool FailHigh;
bool FailLow;
HANDLE SitIdleEvent[THREAD_MAX];
#endif
+ // Node counters, used only by thread[0] but try to keep in different
+ // cache lines (64 bytes each) from the heavy SMP read accessed variables.
+ int NodesSincePoll;
+ int NodesBetweenPolls = 30000;
+
/// Functions
if (UseLogFile)
LogFile.open(get_option_value_string("Search Log Filename").c_str(), std::ios::out | std::ios::app);
- UseQSearchFutilityPruning = get_option_value_bool("Futility Pruning (Quiescence Search)");
- UseFutilityPruning = get_option_value_bool("Futility Pruning (Main Search)");
-
UseLSNFiltering = get_option_value_bool("LSN filtering");
LSNTime = get_option_value_int("LSN Time Margin (sec)") * 1000;
LSNValue = value_from_centipawns(get_option_value_int("LSN Value Margin"));
Value value, bestValue = -VALUE_INFINITE;
Bitboard dcCandidates = mp.discovered_check_candidates();
Value futilityValue = VALUE_NONE;
- bool useFutilityPruning = UseFutilityPruning
- && depth < SelectiveDepth
+ bool useFutilityPruning = depth < SelectiveDepth
&& !isCheck;
// Loop through all legal moves until no moves remain or a beta cutoff
ss[ply].currentMove = move;
// Futility pruning
- if ( UseQSearchFutilityPruning
- && enoughMaterial
+ if ( enoughMaterial
&& !isCheck
&& !pvNode
&& !move_promotion(move)
Value value;
Move move;
bool isCheck = pos.is_check();
- bool useFutilityPruning = UseFutilityPruning
- && sp->depth < SelectiveDepth
+ bool useFutilityPruning = sp->depth < SelectiveDepth
&& !isCheck;
while ( sp->bestValue < sp->beta