1
0
Fork 0

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 change
pull/3714/head
Stéphane Nicolet 2021-09-23 09:54:50 +02:00
parent e8788d1b32
commit 2782caa60a
3 changed files with 33 additions and 9 deletions

View File

@ -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:

View File

@ -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

View File

@ -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;