Remember when TT value equals static evaluation value
authorMarco Costalba <mcostalba@gmail.com>
Mon, 30 Mar 2009 07:54:09 +0000 (08:54 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Mon, 30 Mar 2009 07:54:09 +0000 (08:54 +0100)
When the stored TT value equals the static value set a
proper flag so to not call evaluation() if we hit the
same position again but use the stored TT value instead.

This is another trick to avoid calling costly evaluation()
in qsearch.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/search.cpp
src/tt.cpp
src/tt.h

index 434587a87d5c6e40c627ca3a54edfbad779a1f0d..022f3a9d15b8a08a5c78483490156051e4f732d7 100644 (file)
@@ -1455,7 +1455,7 @@ namespace {
     if (isCheck)
         staticValue = -VALUE_INFINITE;
 
     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));
     {
         // 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));
     if (!pvNode)
     {
         Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1));
+        Value v = value_to_tt(bestValue, ply);
+        TTEntry* e;
         if (bestValue < beta)
         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
         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
     }
 
     // Update killers only for good check moves
index 5c842db85ea3a552a03cae2bf03a04199003bb39..d7b3b7d5b099a7dd91b39808c780067c56baf86f 100644 (file)
@@ -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.
 
 /// 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;
 
                                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);
             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;
     }
     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++;
   }
   *replace = TTEntry(pos.get_key(), v, type, d, m, generation);
   writes++;
+  return replace;
 }
 
 
 }
 
 
index 76ecad81e101254dea4832984f2022dd9e2055da..a820d94ac5181efa74789258c474a167c507ec9e 100644 (file)
--- 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
 /// 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
 
 /// 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); }
   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_;
 
 private:
   Key key_;
@@ -80,7 +83,7 @@ public:
   ~TranspositionTable();
   void set_size(unsigned mbSize);
   void clear();
   ~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[]);
   TTEntry* retrieve(const Position &pos) const;
   void new_search();
   void insert_pv(const Position &pos, Move pv[]);