Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document TT code more #5061

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions src/tt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "tt.h"

#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <iostream>
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
25 changes: 18 additions & 7 deletions src/tt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Loading