mirror of
https://github.com/sockspls/badfish
synced 2025-04-29 16:23:09 +00:00
Document TT code more
Slight refactor of the TT code with the goal to make it easier to understand / tweak. Passed Non-Regression STC: https://tests.stockfishchess.org/tests/view/65d51e401d8e83c78bfdc427 LLR: 2.95 (-2.94,2.94) <-1.75,0.25> Total: 56416 W: 14750 L: 14550 D: 27116 Ptnml(0-2): 227, 6386, 14796, 6558, 241 closes https://github.com/official-stockfish/Stockfish/pull/5061 No functional change
This commit is contained in:
parent
f77eddfa2f
commit
0a3eb1d8fa
2 changed files with 38 additions and 20 deletions
33
src/tt.cpp
33
src/tt.cpp
|
@ -19,6 +19,7 @@
|
|||
#include "tt.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
@ -53,6 +54,18 @@ void TTEntry::save(
|
|||
}
|
||||
|
||||
|
||||
uint8_t TTEntry::relative_age(const uint8_t generation8) const {
|
||||
// Due to our packed storage format for generation and its cyclic
|
||||
// nature we add GENERATION_CYCLE (256 is the modulus, plus what
|
||||
// is needed to keep the unrelated lowest n bits from affecting
|
||||
// the result) to calculate the entry age correctly even after
|
||||
// generation8 overflows into the next cycle.
|
||||
|
||||
return (TranspositionTable::GENERATION_CYCLE + generation8 - genBound8)
|
||||
& TranspositionTable::GENERATION_MASK;
|
||||
}
|
||||
|
||||
|
||||
// Sets the size of the transposition table,
|
||||
// measured in megabytes. Transposition table consists of a power of 2 number
|
||||
// of clusters and each cluster consists of ClusterSize number of TTEntry.
|
||||
|
@ -111,24 +124,18 @@ TTEntry* TranspositionTable::probe(const Key key, bool& found) const {
|
|||
for (int i = 0; i < ClusterSize; ++i)
|
||||
if (tte[i].key16 == key16 || !tte[i].depth8)
|
||||
{
|
||||
tte[i].genBound8 =
|
||||
uint8_t(generation8 | (tte[i].genBound8 & (GENERATION_DELTA - 1))); // Refresh
|
||||
constexpr uint8_t lowerBits = GENERATION_DELTA - 1;
|
||||
|
||||
return found = bool(tte[i].depth8), &tte[i];
|
||||
// Refresh with new generation, keeping the lower bits the same.
|
||||
tte[i].genBound8 = uint8_t(generation8 | (tte[i].genBound8 & lowerBits));
|
||||
return found = bool(tte[i].depth8), &tte[i];
|
||||
}
|
||||
|
||||
// Find an entry to be replaced according to the replacement strategy
|
||||
TTEntry* replace = tte;
|
||||
for (int i = 1; i < ClusterSize; ++i)
|
||||
// Due to our packed storage format for generation and its cyclic
|
||||
// nature we add GENERATION_CYCLE (256 is the modulus, plus what
|
||||
// is needed to keep the unrelated lowest n bits from affecting
|
||||
// the result) to calculate the entry age correctly even after
|
||||
// generation8 overflows into the next cycle.
|
||||
if (replace->depth8
|
||||
- ((GENERATION_CYCLE + generation8 - replace->genBound8) & GENERATION_MASK)
|
||||
> tte[i].depth8
|
||||
- ((GENERATION_CYCLE + generation8 - tte[i].genBound8) & GENERATION_MASK))
|
||||
if (replace->depth8 - replace->relative_age(generation8)
|
||||
> tte[i].depth8 - tte[i].relative_age(generation8))
|
||||
replace = &tte[i];
|
||||
|
||||
return found = false, replace;
|
||||
|
@ -137,7 +144,7 @@ TTEntry* TranspositionTable::probe(const Key key, bool& found) const {
|
|||
|
||||
// Returns an approximation of the hashtable
|
||||
// occupation during a search. The hash is x permill full, as per UCI protocol.
|
||||
|
||||
// Only counts entries which match the current generation.
|
||||
int TranspositionTable::hashfull() const {
|
||||
|
||||
int cnt = 0;
|
||||
|
|
25
src/tt.h
25
src/tt.h
|
@ -46,6 +46,8 @@ struct TTEntry {
|
|||
bool is_pv() const { return bool(genBound8 & 0x4); }
|
||||
Bound bound() const { return Bound(genBound8 & 0x3); }
|
||||
void save(Key k, Value v, bool pv, Bound b, Depth d, Move m, Value ev, uint8_t generation8);
|
||||
// The returned age is a multiple of TranspositionTable::GENERATION_DELTA
|
||||
uint8_t relative_age(const uint8_t generation8) const;
|
||||
|
||||
private:
|
||||
friend class TranspositionTable;
|
||||
|
@ -76,16 +78,25 @@ class TranspositionTable {
|
|||
static_assert(sizeof(Cluster) == 32, "Unexpected Cluster size");
|
||||
|
||||
// Constants used to refresh the hash table periodically
|
||||
static constexpr unsigned GENERATION_BITS = 3; // nb of bits reserved for other things
|
||||
static constexpr int GENERATION_DELTA =
|
||||
(1 << GENERATION_BITS); // increment for generation field
|
||||
static constexpr int GENERATION_CYCLE = 255 + (1 << GENERATION_BITS); // cycle length
|
||||
static constexpr int GENERATION_MASK =
|
||||
(0xFF << GENERATION_BITS) & 0xFF; // mask to pull out generation number
|
||||
|
||||
// We have 8 bits available where the lowest 3 bits are
|
||||
// reserved for other things.
|
||||
static constexpr unsigned GENERATION_BITS = 3;
|
||||
// increment for generation field
|
||||
static constexpr int GENERATION_DELTA = (1 << GENERATION_BITS);
|
||||
// cycle length
|
||||
static constexpr int GENERATION_CYCLE = 255 + GENERATION_DELTA;
|
||||
// mask to pull out generation number
|
||||
static constexpr int GENERATION_MASK = (0xFF << GENERATION_BITS) & 0xFF;
|
||||
|
||||
public:
|
||||
~TranspositionTable() { aligned_large_pages_free(table); }
|
||||
void new_search() { generation8 += GENERATION_DELTA; } // Lower bits are used for other things
|
||||
|
||||
void new_search() {
|
||||
// increment by delta to keep lower bits as is
|
||||
generation8 += GENERATION_DELTA;
|
||||
}
|
||||
|
||||
TTEntry* probe(const Key key, bool& found) const;
|
||||
int hashfull() const;
|
||||
void resize(size_t mbSize, int threadCount);
|
||||
|
|
Loading…
Add table
Reference in a new issue