Always save static value and kingDanger to TT
authorJoona Kiiski <joona.kiiski@gmail.com>
Sat, 22 May 2010 08:56:46 +0000 (11:56 +0300)
committerMarco Costalba <mcostalba@gmail.com>
Sat, 22 May 2010 11:37:11 +0000 (12:37 +0100)
Around 5% speed-up

No functional change

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

index 1a01601b8144f9d68a8cdd0b3c30356acc0d5d68..4a108360a7cee9af7efcf5be646e097de072eae9 100644 (file)
@@ -1095,7 +1095,7 @@ namespace {
     if (!PvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
     {
         // Refresh tte entry to avoid aging
-        TT.store(posKey, tte->value(), tte->type(), tte->depth(), ttMove);
+        TT.store(posKey, tte->value(), tte->type(), tte->depth(), ttMove, tte->static_value(), tte->king_danger());
 
         ss[ply].currentMove = ttMove; // Can be MOVE_NONE
         return value_from_tt(tte->value(), ply);
@@ -1106,8 +1106,11 @@ namespace {
     isCheck = pos.is_check();
     if (!isCheck)
     {
-        if (tte && (tte->type() & VALUE_TYPE_EVAL))
-            ss[ply].eval = value_from_tt(tte->value(), ply);
+        if (tte && tte->static_value() != VALUE_NONE)
+        {
+            ss[ply].eval = tte->static_value();
+            ei.kingDanger[pos.side_to_move()] = tte->king_danger();
+        }
         else
             ss[ply].eval = evaluate(pos, ei, threadID);
 
@@ -1385,13 +1388,13 @@ namespace {
         return bestValue;
 
     if (bestValue <= oldAlpha)
-        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, depth, MOVE_NONE);
+        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, depth, MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
 
     else if (bestValue >= beta)
     {
         TM.incrementBetaCounter(pos.side_to_move(), depth, threadID);
         move = ss[ply].pv[ply];
-        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move);
+        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
         if (!pos.move_is_capture_or_promotion(move))
         {
             update_history(pos, move, depth, movesSearched, moveCount);
@@ -1399,7 +1402,7 @@ namespace {
         }
     }
     else
-        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, depth, ss[ply].pv[ply]);
+        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, depth, ss[ply].pv[ply], ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
 
     assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
 
@@ -1449,8 +1452,6 @@ namespace {
 
     if (!PvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
     {
-        assert(tte->type() != VALUE_TYPE_EVAL);
-
         ss[ply].currentMove = ttMove; // Can be MOVE_NONE
         return value_from_tt(tte->value(), ply);
     }
@@ -1460,8 +1461,11 @@ namespace {
     // Evaluate the position statically
     if (isCheck)
         staticValue = -VALUE_INFINITE;
-    else if (tte && (tte->type() & VALUE_TYPE_EVAL))
-        staticValue = value_from_tt(tte->value(), ply);
+    else if (tte && tte->static_value() != VALUE_NONE)
+    {
+        staticValue = tte->static_value();
+        ei.kingDanger[pos.side_to_move()] = tte->king_danger();
+    }
     else
         staticValue = evaluate(pos, ei, threadID);
 
@@ -1479,7 +1483,7 @@ namespace {
     {
         // Store the score to avoid a future costly evaluation() call
         if (!isCheck && !tte && ei.kingDanger[pos.side_to_move()] == 0)
-            TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EV_LO, Depth(-127*OnePly), MOVE_NONE);
+            TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, Depth(-127*OnePly), MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
 
         return bestValue;
     }
@@ -1577,20 +1581,19 @@ namespace {
     {
         // If bestValue isn't changed it means it is still the static evaluation
         // of the node, so keep this info to avoid a future evaluation() call.
-        ValueType type = (bestValue == staticValue && !ei.kingDanger[pos.side_to_move()] ? VALUE_TYPE_EV_UP : VALUE_TYPE_UPPER);
-        TT.store(pos.get_key(), value_to_tt(bestValue, ply), type, d, MOVE_NONE);
+        TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, d, MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
     }
     else if (bestValue >= beta)
     {
         move = ss[ply].pv[ply];
-        TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move);
+        TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
 
         // Update killers only for good checking moves
         if (!pos.move_is_capture_or_promotion(move))
             update_killers(move, ss[ply]);
     }
     else
-        TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, d, ss[ply].pv[ply]);
+        TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, d, ss[ply].pv[ply], ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
 
     assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
 
index 555f3c6d0e501fc262036eb5c412083ab642fcf2..cded402bdf7ce9782d18552ce10856f772c3d916 100644 (file)
@@ -111,7 +111,7 @@ inline TTEntry* TranspositionTable::first_entry(const Key posKey) const {
 /// is bigger than the depth of t2. A TTEntry of type VALUE_TYPE_EVAL
 /// never replaces another entry for the same position.
 
-void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d, Move m) {
+void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d, Move m, Value statV, Value kingD) {
 
   TTEntry *tte, *replace;
   uint32_t posKey32 = posKey >> 32; // Use the high 32 bits as key
@@ -125,7 +125,7 @@ void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d,
           if (m == MOVE_NONE)
               m = tte->move();
 
-          *tte = TTEntry(posKey32, v, t, d, m, generation);
+          *tte = TTEntry(posKey32, v, t, d, m, generation, statV, kingD);
           return;
       }
       else if (i == 0)  // replace would be a no-op in this common case
@@ -138,7 +138,7 @@ void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d,
       if (c1 + c2 + c3 > 0)
           replace = tte;
   }
-  *replace = TTEntry(posKey32, v, t, d, m, generation);
+  *replace = TTEntry(posKey32, v, t, d, m, generation, statV, kingD);
   writes++;
 }
 
@@ -211,7 +211,7 @@ void TranspositionTable::insert_pv(const Position& pos, Move pv[]) {
   {
       TTEntry *tte = retrieve(p.get_key());
       if (!tte || tte->move() != pv[i])
-          store(p.get_key(), VALUE_NONE, VALUE_TYPE_NONE, Depth(-127*OnePly), pv[i]);
+          store(p.get_key(), VALUE_NONE, VALUE_TYPE_NONE, Depth(-127*OnePly), pv[i], VALUE_NONE, VALUE_NONE);
       p.do_move(pv[i], st);
   }
 }
index 530cc4053719f168a25e5f389a82e6160eb4f6fd..c8f7d548fbda4a663fec02014fba347cf2d79ab6 100644 (file)
--- a/src/tt.h
+++ b/src/tt.h
@@ -54,9 +54,11 @@ class TTEntry {
 
 public:
   TTEntry() {}
-  TTEntry(uint32_t k, Value v, ValueType t, Depth d, Move m, int generation)
+  TTEntry(uint32_t k, Value v, ValueType t, Depth d, Move m, int generation,
+          Value statV, Value kingD)
         : key_ (k), data((m & 0x1FFFF) | (t << 20) | (generation << 23)),
-          value_(int16_t(v)), depth_(int16_t(d)) {}
+          value_(int16_t(v)), depth_(int16_t(d)),
+          staticValue_(int16_t(statV)), kingDanger_(int16_t(kingD)) {}
 
   uint32_t key() const { return key_; }
   Depth depth() const { return Depth(depth_); }
@@ -64,12 +66,16 @@ public:
   Value value() const { return Value(value_); }
   ValueType type() const { return ValueType((data >> 20) & 7); }
   int generation() const { return (data >> 23); }
+  Value static_value() const { return Value(staticValue_); }
+  Value king_danger() const { return Value(kingDanger_); }
 
 private:
   uint32_t key_;
   uint32_t data;
   int16_t value_;
   int16_t depth_;
+  int16_t staticValue_;
+  int16_t kingDanger_;
 };
 
 
@@ -97,7 +103,7 @@ public:
   ~TranspositionTable();
   void set_size(size_t mbSize);
   void clear();
-  void store(const Key posKey, Value v, ValueType type, Depth d, Move m);
+  void store(const Key posKey, Value v, ValueType type, Depth d, Move m, Value statV, Value kingD);
   TTEntry* retrieve(const Key posKey) const;
   void prefetch(const Key posKey) const;
   void new_search();
index ed2bbb24ff9f5deac20cb6264b915c7297973a32..4c082260eecdd68e5acfa5315dc95a510d3171d4 100644 (file)
@@ -36,11 +36,7 @@ enum ValueType {
   VALUE_TYPE_NONE  = 0,
   VALUE_TYPE_UPPER = 1,  // Upper bound
   VALUE_TYPE_LOWER = 2,  // Lower bound
-  VALUE_TYPE_EVAL  = 4,  // Static evaluation value
-
-  VALUE_TYPE_EXACT = VALUE_TYPE_UPPER | VALUE_TYPE_LOWER,
-  VALUE_TYPE_EV_UP = VALUE_TYPE_EVAL  | VALUE_TYPE_UPPER,
-  VALUE_TYPE_EV_LO = VALUE_TYPE_EVAL  | VALUE_TYPE_LOWER
+  VALUE_TYPE_EXACT = VALUE_TYPE_UPPER | VALUE_TYPE_LOWER
 };