diff --git a/src/search.cpp b/src/search.cpp index 434587a8..022f3a9d 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1455,7 +1455,7 @@ namespace { if (isCheck) staticValue = -VALUE_INFINITE; - else if (tte && tte->type() == VALUE_TYPE_EVAL) + else if (tte && (tte->type() == VALUE_TYPE_EVAL || tte->staticValue())) { // Use the cached evaluation score if possible assert(tte->value() == evaluate(pos, ei, threadID)); @@ -1569,10 +1569,21 @@ namespace { if (!pvNode) { Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1)); + Value v = value_to_tt(bestValue, ply); + TTEntry* e; if (bestValue < beta) - TT.store(pos, value_to_tt(bestValue, ply), d, MOVE_NONE, VALUE_TYPE_UPPER); + e = TT.store(pos, v, d, MOVE_NONE, VALUE_TYPE_UPPER); else - TT.store(pos, value_to_tt(bestValue, ply), d, MOVE_NONE, VALUE_TYPE_LOWER); + e = TT.store(pos, v, d, MOVE_NONE, VALUE_TYPE_LOWER); + + assert(e && e == TT.retrieve(pos)); + assert(!e->staticValue()); + + // If the just stored value happens to be equal to the static evaluation + // score then set the flag, so to avoid calling evaluation() next time we + // hit this position. + if (staticValue == v && !ei.futilityMargin) + e->setStaticValue(); } // Update killers only for good check moves diff --git a/src/tt.cpp b/src/tt.cpp index 5c842db8..d7b3b7d5 100644 --- a/src/tt.cpp +++ b/src/tt.cpp @@ -103,7 +103,7 @@ void TranspositionTable::clear() { /// current search and t2 is from a previous search, or if the depth of t1 /// is bigger than the depth of t2. -void TranspositionTable::store(const Position &pos, Value v, Depth d, +TTEntry* TranspositionTable::store(const Position &pos, Value v, Depth d, Move m, ValueType type) { TTEntry *tte, *replace; @@ -116,7 +116,7 @@ void TranspositionTable::store(const Position &pos, Value v, Depth d, m = tte->move(); *tte = TTEntry(pos.get_key(), v, type, d, m, generation); - return; + return tte; } else if (i == 0) // replace would be a no-op in this common case continue; @@ -130,6 +130,7 @@ void TranspositionTable::store(const Position &pos, Value v, Depth d, } *replace = TTEntry(pos.get_key(), v, type, d, m, generation); writes++; + return replace; } diff --git a/src/tt.h b/src/tt.h index 76ecad81..a820d94a 100644 --- a/src/tt.h +++ b/src/tt.h @@ -46,7 +46,8 @@ /// the 32 bits of the data field are so defined /// /// bit 0-16: move -/// bit 17-19: not used +/// bit 17: stored value equals static value +/// bit 18-19: not used /// bit 20-22: value type /// bit 23-31: generation @@ -61,6 +62,8 @@ public: Value value() const { return Value(value_); } ValueType type() const { return ValueType((data >> 20) & 7); } int generation() const { return (data >> 23); } + bool staticValue() const { return ((data >> 17) & 1); } + void setStaticValue() { data |= (1 << 17); } private: Key key_; @@ -80,7 +83,7 @@ public: ~TranspositionTable(); void set_size(unsigned mbSize); void clear(); - void store(const Position &pos, Value v, Depth d, Move m, ValueType type); + TTEntry* store(const Position &pos, Value v, Depth d, Move m, ValueType type); TTEntry* retrieve(const Position &pos) const; void new_search(); void insert_pv(const Position &pos, Move pv[]);