#include <algorithm>
#include <cassert>
+#include <cfloat>
#include <cmath>
#include <cstring>
#include <iostream>
// Set to true to force running with one thread. Used for debugging
const bool FakeSplit = false;
- // This is the minimum interval in msec between two check_time() calls
- const int TimerResolution = 5;
-
// Different node types, used as template parameter
enum NodeType { Root, PV, NonPV, SplitPointRoot, SplitPointPV, SplitPointNonPV };
if (Reductions[0][0][hd][mc] > 2 * ONE_PLY)
Reductions[0][0][hd][mc] += ONE_PLY;
+
+ else if (Reductions[0][0][hd][mc] > 1 * ONE_PLY)
+ Reductions[0][0][hd][mc] += ONE_PLY / 2;
}
// Init futility margins array
for (d = 1; d < 16; ++d) for (mc = 0; mc < 64; ++mc)
- FutilityMargins[d][mc] = Value(112 * int(log(double(d * d) / 2) / log(2.0) + 1.001) - 8 * mc + 45);
+ FutilityMargins[d][mc] = Value(112 * int(2.9 * log(double(d))) - 8 * mc + 45);
// Init futility move count array
for (d = 0; d < 32; ++d)
{
- FutilityMoveCounts[0][d] = int(3 + 0.3 * pow(double(d ), 1.8)) * 3/4 + (2 < d && d < 5);
- FutilityMoveCounts[1][d] = int(3 + 0.3 * pow(double(d + 0.98), 1.8));
+ FutilityMoveCounts[0][d] = int(2.4 + 0.222 * pow(d + 0.0, 1.8));
+ FutilityMoveCounts[1][d] = int(3.0 + 0.3 * pow(d + 0.98, 1.8));
}
}
Threads[i]->maxPly = 0;
Threads.sleepWhileIdle = Options["Idle Threads Sleep"];
-
- // Set best timer interval to avoid lagging under time pressure. Timer is
- // used to check for remaining available thinking time.
- Threads.timer->msec =
- Limits.use_time_management() ? std::min(100, std::max(TimeMgr.available_time() / 16, TimerResolution)) :
- Limits.nodes ? 2 * TimerResolution
- : 100;
-
+ Threads.timer->run = true;
Threads.timer->notify_one(); // Wake up the recurring timer
id_loop(RootPos); // Let's start searching !
- Threads.timer->msec = 0; // Stop the timer
+ Threads.timer->run = false; // Stop the timer
Threads.sleepWhileIdle = true; // Send idle threads to sleep
if (Options["Write Search Log"])
// Stop search early if one move seems to be much better than others
if ( depth >= 12
+ && BestMoveChanges <= DBL_EPSILON
&& !stop
&& PVSize == 1
&& bestValue > VALUE_MATED_IN_MAX_PLY
if ( (ss->staticEval = bestValue = tte->eval_value()) == VALUE_NONE
||(ss->evalMargin = tte->eval_margin()) == VALUE_NONE)
ss->staticEval = bestValue = evaluate(pos, ss->evalMargin);
+
+ // Can ttValue be used as a better position evaluation?
+ if (ttValue != VALUE_NONE)
+ if (tte->bound() & (ttValue > bestValue ? BOUND_LOWER : BOUND_UPPER))
+ bestValue = ttValue;
}
else
ss->staticEval = bestValue = evaluate(pos, ss->evalMargin);
if (PvNode && bestValue > alpha)
alpha = bestValue;
- futilityBase = ss->staticEval + ss->evalMargin + Value(128);
+ futilityBase = bestValue + ss->evalMargin + Value(128);
}
// Initialize a MovePicker object for the current position, and prepare
&& !Signals.failedLowAtRoot
&& elapsed > TimeMgr.available_time();
- bool noMoreTime = elapsed > TimeMgr.maximum_time() - 2 * TimerResolution
+ bool noMoreTime = elapsed > TimeMgr.maximum_time() - 2 * TimerThread::Resolution
|| stillAtFirstMove;
if ( (Limits.use_time_management() && noMoreTime)