Refactor Thread class
[stockfish] / src / tt.h
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-2012 Marco Costalba, Joona Kiiski, Tord Romstad
5
6   Stockfish is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   Stockfish is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #if !defined(TT_H_INCLUDED)
21 #define TT_H_INCLUDED
22
23 #include <iostream>
24
25 #include "misc.h"
26 #include "types.h"
27
28
29 /// The TTEntry is the class of transposition table entries
30 ///
31 /// A TTEntry needs 128 bits to be stored
32 ///
33 /// bit  0-31: key
34 /// bit 32-63: data
35 /// bit 64-79: value
36 /// bit 80-95: depth
37 /// bit 96-111: static value
38 /// bit 112-127: margin of static value
39 ///
40 /// the 32 bits of the data field are so defined
41 ///
42 /// bit  0-15: move
43 /// bit 16-20: not used
44 /// bit 21-22: value type
45 /// bit 23-31: generation
46
47 class TTEntry {
48
49 public:
50   void save(uint32_t k, Value v, Bound b, Depth d, Move m, int g, Value statV, Value statM) {
51
52     key32        = (uint32_t)k;
53     move16       = (uint16_t)m;
54     bound        = (uint8_t)b;
55     generation8  = (uint8_t)g;
56     value16      = (int16_t)v;
57     depth16      = (int16_t)d;
58     staticValue  = (int16_t)statV;
59     staticMargin = (int16_t)statM;
60   }
61   void set_generation(int g) { generation8 = (uint8_t)g; }
62
63   uint32_t key() const              { return key32; }
64   Depth depth() const               { return (Depth)depth16; }
65   Move move() const                 { return (Move)move16; }
66   Value value() const               { return (Value)value16; }
67   Bound type() const                { return (Bound)bound; }
68   int generation() const            { return (int)generation8; }
69   Value static_value() const        { return (Value)staticValue; }
70   Value static_value_margin() const { return (Value)staticMargin; }
71
72 private:
73   uint32_t key32;
74   uint16_t move16;
75   uint8_t bound, generation8;
76   int16_t value16, depth16, staticValue, staticMargin;
77 };
78
79
80 /// This is the number of TTEntry slots for each cluster
81 const int ClusterSize = 4;
82
83
84 /// TTCluster consists of ClusterSize number of TTEntries. Size of TTCluster
85 /// must not be bigger than a cache line size. In case it is less, it should
86 /// be padded to guarantee always aligned accesses.
87
88 struct TTCluster {
89   TTEntry data[ClusterSize];
90 };
91
92
93 /// The transposition table class. This is basically just a huge array containing
94 /// TTCluster objects, and a few methods for writing and reading entries.
95
96 class TranspositionTable {
97
98   TranspositionTable(const TranspositionTable&);
99   TranspositionTable& operator=(const TranspositionTable&);
100
101 public:
102   TranspositionTable();
103   ~TranspositionTable();
104   void set_size(size_t mbSize);
105   void clear();
106   void store(const Key posKey, Value v, Bound type, Depth d, Move m, Value statV, Value kingD);
107   TTEntry* probe(const Key posKey) const;
108   void new_search();
109   TTEntry* first_entry(const Key posKey) const;
110   void refresh(const TTEntry* tte) const;
111
112 private:
113   size_t size;
114   TTCluster* entries;
115   uint8_t generation; // Size must be not bigger then TTEntry::generation8
116 };
117
118 extern TranspositionTable TT;
119
120
121 /// TranspositionTable::first_entry() returns a pointer to the first entry of
122 /// a cluster given a position. The lowest order bits of the key are used to
123 /// get the index of the cluster.
124
125 inline TTEntry* TranspositionTable::first_entry(const Key posKey) const {
126
127   return entries[((uint32_t)posKey) & (size - 1)].data;
128 }
129
130
131 /// TranspositionTable::refresh() updates the 'generation' value of the TTEntry
132 /// to avoid aging. Normally called after a TT hit.
133
134 inline void TranspositionTable::refresh(const TTEntry* tte) const {
135
136   const_cast<TTEntry*>(tte)->set_generation(generation);
137 }
138
139
140 /// A simple fixed size hash table used to store pawns and material
141 /// configurations. It is basically just an array of Entry objects.
142 /// Without cluster concept or overwrite policy.
143
144 template<class Entry, int HashSize>
145 struct SimpleHash {
146
147   typedef SimpleHash<Entry, HashSize> Base;
148
149   SimpleHash() {
150
151     entries = new (std::nothrow) Entry[HashSize];
152     if (!entries)
153     {
154         std::cerr << "Failed to allocate " << HashSize * sizeof(Entry)
155                   << " bytes for hash table." << std::endl;
156         exit(EXIT_FAILURE);
157     }
158     memset(entries, 0, HashSize * sizeof(Entry));
159   }
160
161   virtual ~SimpleHash() { delete [] entries; }
162
163   Entry* probe(Key key) const { return entries + ((uint32_t)key & (HashSize - 1)); }
164   void prefetch(Key key) const { ::prefetch((char*)probe(key)); }
165
166 protected:
167   Entry* entries;
168 };
169
170 #endif // !defined(TT_H_INCLUDED)