Subversion Repositories Games.Chess Giants

Rev

Rev 96 | Rev 169 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.   Stockfish, a UCI chess playing engine derived from Glaurung 2.1
  3.   Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
  4.   Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
  5.   Copyright (C) 2015-2016 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
  6.  
  7.   Stockfish is free software: you can redistribute it and/or modify
  8.   it under the terms of the GNU General Public License as published by
  9.   the Free Software Foundation, either version 3 of the License, or
  10.   (at your option) any later version.
  11.  
  12.   Stockfish is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License
  18.   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19. */
  20.  
  21. #ifndef TT_H_INCLUDED
  22. #define TT_H_INCLUDED
  23.  
  24. #include "misc.h"
  25. #include "types.h"
  26.  
  27. /// TTEntry struct is the 10 bytes transposition table entry, defined as below:
  28. ///
  29. /// key        16 bit
  30. /// move       16 bit
  31. /// value      16 bit
  32. /// eval value 16 bit
  33. /// generation  6 bit
  34. /// bound type  2 bit
  35. /// depth       8 bit
  36.  
  37. struct TTEntry {
  38.  
  39.   Move  move()  const { return (Move )move16; }
  40.   Value value() const { return (Value)value16; }
  41.   Value eval()  const { return (Value)eval16; }
  42.   Depth depth() const { return (Depth)(depth8 * int(ONE_PLY)); }
  43.   Bound bound() const { return (Bound)(genBound8 & 0x3); }
  44.  
  45.   void save(Key k, Value v, Bound b, Depth d, Move m, Value ev, uint8_t g) {
  46.  
  47.     assert(d / ONE_PLY * ONE_PLY == d);
  48.  
  49.     // Preserve any existing move for the same position
  50.     if (m || (k >> 48) != key16)
  51.         move16 = (uint16_t)m;
  52.  
  53.     // Don't overwrite more valuable entries
  54.     if (  (k >> 48) != key16
  55.         || d / ONE_PLY > depth8 - 4
  56.      /* || g != (genBound8 & 0xFC) // Matching non-zero keys are already refreshed by probe() */
  57.         || b == BOUND_EXACT)
  58.     {
  59.         key16     = (uint16_t)(k >> 48);
  60.         value16   = (int16_t)v;
  61.         eval16    = (int16_t)ev;
  62.         genBound8 = (uint8_t)(g | b);
  63.         depth8    = (int8_t)(d / ONE_PLY);
  64.     }
  65.   }
  66.  
  67. private:
  68.   friend class TranspositionTable;
  69.  
  70.   uint16_t key16;
  71.   uint16_t move16;
  72.   int16_t  value16;
  73.   int16_t  eval16;
  74.   uint8_t  genBound8;
  75.   int8_t   depth8;
  76. };
  77.  
  78.  
  79. /// A TranspositionTable consists of a power of 2 number of clusters and each
  80. /// cluster consists of ClusterSize number of TTEntry. Each non-empty entry
  81. /// contains information of exactly one position. The size of a cluster should
  82. /// divide the size of a cache line size, to ensure that clusters never cross
  83. /// cache lines. This ensures best cache performance, as the cacheline is
  84. /// prefetched, as soon as possible.
  85.  
  86. class TranspositionTable {
  87.  
  88.   static const int CacheLineSize = 64;
  89.   static const int ClusterSize = 3;
  90.  
  91.   struct Cluster {
  92.     TTEntry entry[ClusterSize];
  93.     char padding[2]; // Align to a divisor of the cache line size
  94.   };
  95.  
  96.   static_assert(CacheLineSize % sizeof(Cluster) == 0, "Cluster size incorrect");
  97.  
  98. public:
  99.  ~TranspositionTable() { free(mem); }
  100.   void new_search() { generation8 += 4; } // Lower 2 bits are used by Bound
  101.   uint8_t generation() const { return generation8; }
  102.   TTEntry* probe(const Key key, bool& found) const;
  103.   int hashfull() const;
  104.   void resize(size_t mbSize);
  105.   void clear();
  106.  
  107.   // The lowest order bits of the key are used to get the index of the cluster
  108.   TTEntry* first_entry(const Key key) const {
  109.     return &table[(size_t)key & (clusterCount - 1)].entry[0];
  110.   }
  111.  
  112. private:
  113.   size_t clusterCount;
  114.   Cluster* table;
  115.   void* mem;
  116.   uint8_t generation8; // Size must be not bigger than TTEntry::genBound8
  117. };
  118.  
  119. extern TranspositionTable TT;
  120.  
  121. #endif // #ifndef TT_H_INCLUDED
  122.