From: Marco Costalba Date: Tue, 11 Aug 2009 07:30:19 +0000 (+0100) Subject: Reuse 5 slots instead of 4 X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=166c09a7a0eafb706a961d6533c73cc248f6df94 Reuse 5 slots instead of 4 But this time with the guarantee of an always aligned access so that prefetching is not adversely impacted. On Joona PC 1+0, 64Mb hash: Orig - Mod: 174 - 237 - 359 Instead after 1000 games at 1+0 with 128MB hash size we are at + 1 ELO (just 4 games of difference). Signed-off-by: Marco Costalba --- diff --git a/src/tt.cpp b/src/tt.cpp index ffb8b012..5ea6a808 100644 --- a/src/tt.cpp +++ b/src/tt.cpp @@ -33,9 +33,6 @@ #include #endif -// This is the number of TTEntry slots for each position -static const int ClusterSize = 4; - // The main transposition table TranspositionTable TT; @@ -67,14 +64,14 @@ void TranspositionTable::set_size(unsigned mbSize) { // We store a cluster of ClusterSize number of TTEntry for each position // and newSize is the maximum number of storable positions. - while ((2 * newSize) * ClusterSize * (sizeof(TTEntry)) <= (mbSize << 20)) + while ((2 * newSize) * sizeof(TTCluster) <= (mbSize << 20)) newSize *= 2; if (newSize != size) { size = newSize; delete [] entries; - entries = new TTEntry[size * ClusterSize]; + entries = new TTCluster[size]; if (!entries) { std::cerr << "Failed to allocate " << mbSize @@ -93,7 +90,7 @@ void TranspositionTable::set_size(unsigned mbSize) { void TranspositionTable::clear() { - memset(entries, 0, size * ClusterSize * sizeof(TTEntry)); + memset(entries, 0, size * sizeof(TTCluster)); } @@ -103,7 +100,7 @@ void TranspositionTable::clear() { inline TTEntry* TranspositionTable::first_entry(const Key posKey) const { - return entries + ((uint32_t(posKey) & (size - 1)) * ClusterSize); + return entries[uint32_t(posKey) & (size - 1)].data; } diff --git a/src/tt.h b/src/tt.h index e838b090..2c989dac 100644 --- a/src/tt.h +++ b/src/tt.h @@ -70,10 +70,23 @@ private: uint32_t data; int16_t value_; int16_t depth_; - uint32_t pad_to_16_bytes; }; -/// The transposition table class. This is basically just a huge array + +/// This is the number of TTEntry slots for each position +const int ClusterSize = 5; + +/// Each group of ClusterSize number of TTEntry form a TTCluster +/// that is indexed by a single position key. Cluster is padded +/// to a cache line size so to guarantee always aligned accesses. + +struct TTCluster { + TTEntry data[ClusterSize]; + char cache_line_padding[64 - sizeof(TTEntry[ClusterSize])]; +}; + + +/// The transposition table class. This is basically just a huge array /// containing TTEntry objects, and a few methods for writing new entries /// and reading new ones. @@ -95,14 +108,14 @@ public: private: inline TTEntry* first_entry(const Key posKey) const; - // Be sure 'writes' is at least one cacheline away + // Be sure 'writes' is at least one cache line away // from read only variables. unsigned char pad_before[64 - sizeof(unsigned)]; unsigned writes; // heavy SMP read/write access here unsigned char pad_after[64]; unsigned size; - TTEntry* entries; + TTCluster* entries; uint8_t generation; };