Skip to content

Commit 166bf90

Browse files
sessesnicolet
authored andcommitted
Shrink the hash table of tablebases back to 4096 entries
There is no need to make this as large as 65536 just for the sake of the single 7-man tablebase that happens to have the key 0xf9247fff. Idea for the fix by Ronald de Man, who suggested simply to allow more buckets past the end. We also implement Robin Hood hashing for the hash table, which takes the worst -case search for full 7-man tablebases down from 68 to 11 probes (Also takes the average probe length from 2.06 to 2.05). For a table with 8K entries, the corresponding numbers would be worst-case from 9 to 4, with average from 1.30 to 1.29. #1747 No functional change
1 parent 4aa091c commit 166bf90

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

Readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ The "SyzygyProbeLimit" option should normally be left at its default value.
5959

6060
**What to expect**
6161
If the engine is searching a position that is not in the tablebases (e.g.
62-
a position with 7 pieces), it will access the tablebases during the search.
62+
a position with 8 pieces), it will access the tablebases during the search.
6363
If the engine reports a very large score (typically 123.xx), this means
6464
that it has found a winning line into a tablebase position.
6565

src/syzygy/tbprobe.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -384,22 +384,35 @@ class TBTables {
384384

385385
typedef std::tuple<Key, TBTable<WDL>*, TBTable<DTZ>*> Entry;
386386

387-
static const int Size = 1 << 16; // 64K table, indexed by key's 16 lsb
387+
static constexpr int Size = 1 << 12; // 4K table, indexed by key's 12 lsb
388+
static constexpr int Overflow = 1; // Number of elements allowed to map to the last bucket
388389

389-
Entry hashTable[Size];
390+
Entry hashTable[Size + Overflow];
390391

391392
std::deque<TBTable<WDL>> wdlTable;
392393
std::deque<TBTable<DTZ>> dtzTable;
393394

394395
void insert(Key key, TBTable<WDL>* wdl, TBTable<DTZ>* dtz) {
395-
Entry* entry = &hashTable[(uint32_t)key & (Size - 1)];
396+
uint32_t homeBucket = (uint32_t)key & (Size - 1);
397+
Entry entry = std::make_tuple(key, wdl, dtz);
396398

397399
// Ensure last element is empty to avoid overflow when looking up
398-
for ( ; entry - hashTable < Size - 1; ++entry)
399-
if (std::get<KEY>(*entry) == key || !std::get<WDL>(*entry)) {
400-
*entry = std::make_tuple(key, wdl, dtz);
400+
for (uint32_t bucket = homeBucket; bucket < Size + Overflow - 1; ++bucket) {
401+
Key otherKey = std::get<KEY>(hashTable[bucket]);
402+
if (otherKey == key || !std::get<WDL>(hashTable[bucket])) {
403+
hashTable[bucket] = entry;
401404
return;
402405
}
406+
407+
// Robin Hood hashing: If we've probed for longer than this element,
408+
// insert here and search for a new spot for the other element instead.
409+
uint32_t otherHomeBucket = (uint32_t)otherKey & (Size - 1);
410+
if (otherHomeBucket > homeBucket) {
411+
swap(entry, hashTable[bucket]);
412+
key = otherKey;
413+
homeBucket = otherHomeBucket;
414+
}
415+
}
403416
std::cerr << "TB hash table size too low!" << std::endl;
404417
exit(1);
405418
}

0 commit comments

Comments
 (0)