Subversion Repositories Games.Chess Giants

Rev

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; }
  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.     // Preserve any existing move for the same position
  48.     if (m || (k >> 48) != key16)
  49.         move16 = (uint16_t)m;
  50.  
  51.     // Don't overwrite more valuable entries
  52.     if (  (k >> 48) != key16
  53.         || d > depth8 - 4
  54.      /* || g != (genBound8 & 0xFC) // Matching non-zero keys are already refreshed by probe() */
  55.         || b == BOUND_EXACT)
  56.     {
  57.         key16     = (uint16_t)(k >> 48);
  58.         value16   = (int16_t)v;
  59.         eval16    = (int16_t)ev;
  60.         genBound8 = (uint8_t)(g | b);
  61.         depth8    = (int8_t)d;
  62.     }
  63.   }
  64.  
  65. private:
  66.   friend class TranspositionTable;
  67.  
  68.   uint16_t key16;
  69.   uint16_t move16;
  70.   int16_t  value16;
  71.   int16_t  eval16;
  72.   uint8_t  genBound8;
  73.   int8_t   depth8;
  74. };
  75.  
  76.  
  77. /// A TranspositionTable consists of a power of 2 number of clusters and each
  78. /// cluster consists of ClusterSize number of TTEntry. Each non-empty entry
  79. /// contains information of exactly one position. The size of a cluster should
  80. /// divide the size of a cache line size, to ensure that clusters never cross
  81. /// cache lines. This ensures best cache performance, as the cacheline is
  82. /// prefetched, as soon as possible.
  83.  
  84. class TranspositionTable {
  85.  
  86.   static const int CacheLineSize = 64;
  87.   static const int ClusterSize = 3;
  88.  
  89.   struct Cluster {
  90.     TTEntry entry[ClusterSize];
  91.     char padding[2]; // Align to a divisor of the cache line size
  92.   };
  93.  
  94.   static_assert(CacheLineSize % sizeof(Cluster) == 0, "Cluster size incorrect");
  95.  
  96. public:
  97.  ~TranspositionTable() { free(mem); }
  98.   void new_search() { generation8 += 4; } // Lower 2 bits are used by Bound
  99.   uint8_t generation() const { return generation8; }
  100.   TTEntry* probe(const Key key, bool& found) const;
  101.   int hashfull() const;
  102.   void resize(size_t mbSize);
  103.   void clear();
  104.  
  105.   // The lowest order bits of the key are used to get the index of the cluster
  106.   TTEntry* first_entry(const Key key) const {
  107.     return &table[(size_t)key & (clusterCount - 1)].entry[0];
  108.   }
  109.  
  110. private:
  111.   size_t clusterCount;
  112.   Cluster* table;
  113.   void* mem;
  114.   uint8_t generation8; // Size must be not bigger than TTEntry::genBound8
  115. };
  116.  
  117. extern TranspositionTable TT;
  118.  
  119. #endif // #ifndef TT_H_INCLUDED
  120.