Introduce RunningAverage class
A class to calculate a running average of a series of values, generalizing the ttHitAverage variable we already have in code. For efficiency, all computations are done with integers. The implementation uses an exponential moving average of period 4096 and resolution 1/1024. See https://github.com/official-stockfish/Stockfish/pull/3714 No functional changepull/3714/head
parent
e8788d1b32
commit
2782caa60a
27
src/misc.h
27
src/misc.h
|
@ -85,6 +85,33 @@ static inline const union { uint32_t i; char c[4]; } Le = { 0x01020304 };
|
|||
static inline const bool IsLittleEndian = (Le.c[0] == 4);
|
||||
|
||||
|
||||
// RunningAverage : a class to calculate a running average of a series of values.
|
||||
// For efficiency, all computations are done with integers.
|
||||
class RunningAverage {
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
RunningAverage() {}
|
||||
|
||||
// Reset the running average to rational value p / q
|
||||
void set(int64_t p, int64_t q)
|
||||
{ average = p * PERIOD * RESOLUTION / q; }
|
||||
|
||||
// Update average with value v
|
||||
void update(int64_t v)
|
||||
{ average = RESOLUTION * v + (PERIOD - 1) * average / PERIOD; }
|
||||
|
||||
// Test if average is strictly greater than rational a / b
|
||||
bool is_greater(int64_t a, int64_t b)
|
||||
{ return b * average > a * PERIOD * RESOLUTION ; }
|
||||
|
||||
private :
|
||||
static constexpr int64_t PERIOD = 4096;
|
||||
static constexpr int64_t RESOLUTION = 1024;
|
||||
int64_t average;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class ValueListInserter {
|
||||
public:
|
||||
|
|
|
@ -61,9 +61,6 @@ namespace {
|
|||
// Different node types, used as a template parameter
|
||||
enum NodeType { NonPV, PV, Root };
|
||||
|
||||
constexpr uint64_t TtHitAverageWindow = 4096;
|
||||
constexpr uint64_t TtHitAverageResolution = 1024;
|
||||
|
||||
// Futility margin
|
||||
Value futility_margin(Depth d, bool improving) {
|
||||
return Value(214 * (d - improving));
|
||||
|
@ -310,7 +307,8 @@ void Thread::search() {
|
|||
multiPV = std::max(multiPV, (size_t)4);
|
||||
|
||||
multiPV = std::min(multiPV, rootMoves.size());
|
||||
ttHitAverage = TtHitAverageWindow * TtHitAverageResolution / 2;
|
||||
|
||||
ttHitAverage.set(50, 100); // initialize the running average at 50%
|
||||
|
||||
trend = SCORE_ZERO;
|
||||
|
||||
|
@ -632,9 +630,8 @@ namespace {
|
|||
&& is_ok((ss-1)->currentMove))
|
||||
thisThread->lowPlyHistory[ss->ply - 1][from_to((ss-1)->currentMove)] << stat_bonus(depth - 5);
|
||||
|
||||
// thisThread->ttHitAverage can be used to approximate the running average of ttHit
|
||||
thisThread->ttHitAverage = (TtHitAverageWindow - 1) * thisThread->ttHitAverage / TtHitAverageWindow
|
||||
+ TtHitAverageResolution * ss->ttHit;
|
||||
// running average of ttHit
|
||||
thisThread->ttHitAverage.update(ss->ttHit);
|
||||
|
||||
// At non-PV nodes we check for an early TT cutoff
|
||||
if ( !PvNode
|
||||
|
@ -1146,7 +1143,7 @@ moves_loop: // When in check, search starts here
|
|||
r--;
|
||||
|
||||
// Decrease reduction if the ttHit running average is large (~0 Elo)
|
||||
if (thisThread->ttHitAverage > 537 * TtHitAverageResolution * TtHitAverageWindow / 1024)
|
||||
if (thisThread->ttHitAverage.is_greater(537, 1024))
|
||||
r--;
|
||||
|
||||
// Decrease reduction if position is or has been on the PV
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
Pawns::Table pawnsTable;
|
||||
Material::Table materialTable;
|
||||
size_t pvIdx, pvLast;
|
||||
uint64_t ttHitAverage;
|
||||
RunningAverage ttHitAverage;
|
||||
int selDepth, nmpMinPly;
|
||||
Color nmpColor;
|
||||
std::atomic<uint64_t> nodes, tbHits, bestMoveChanges;
|
||||
|
|
Loading…
Reference in New Issue