1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-05-02 09:39:36 +00:00

Rework hash table access

This commit is contained in:
Marco Costalba 2016-04-21 11:58:32 +02:00
parent b4985de966
commit 8db35c8a5f

View file

@ -151,11 +151,6 @@ struct DTZEntry_pawn {
uint8_t *map; uint8_t *map;
}; };
struct TBHashEntry {
uint64_t key;
struct TBEntry *ptr;
};
struct DTZTableEntry { struct DTZTableEntry {
uint64_t key1; uint64_t key1;
uint64_t key2; uint64_t key2;
@ -370,8 +365,6 @@ const Value WDL_to_value[] = {
const int DTZ_ENTRIES = 64; const int DTZ_ENTRIES = 64;
const int TBMAX_PIECE = 254; const int TBMAX_PIECE = 254;
const int TBMAX_PAWN = 256; const int TBMAX_PAWN = 256;
const int TBHASHBITS = 10;
const int HSHMAX = 5;
const std::string PieceChar = " PNBRQK"; const std::string PieceChar = " PNBRQK";
@ -381,16 +374,59 @@ Mutex TB_mutex;
std::string TBPaths; std::string TBPaths;
TBEntry_piece TB_piece[TBMAX_PIECE]; TBEntry_piece TB_piece[TBMAX_PIECE];
TBEntry_pawn TB_pawn[TBMAX_PAWN]; TBEntry_pawn TB_pawn[TBMAX_PAWN];
TBHashEntry TB_hash[1 << TBHASHBITS][HSHMAX];
DTZTableEntry DTZ_table[DTZ_ENTRIES]; DTZTableEntry DTZ_table[DTZ_ENTRIES];
int Binomial[5][64]; int Binomial[5][64];
int Pawnidx[5][24]; int Pawnidx[5][24];
int Pfactor[5][4]; int Pfactor[5][4];
class HashTable {
struct Entry {
Key key;
struct TBEntry* ptr;
};
static const int TBHASHBITS = 10;
static const int HSHMAX = 5;
Entry table[1 << TBHASHBITS][HSHMAX];
public:
TBEntry* operator[](Key key) {
Entry* entry = table[key >> (64 - TBHASHBITS)];
for (int i = 0; i < HSHMAX; i++, entry++)
if (entry->key == key)
return entry->ptr;
return nullptr;
}
void insert(TBEntry* ptr, Key key) {
Entry* entry = table[key >> (64 - TBHASHBITS)];
for (int i = 0; i < HSHMAX; i++, entry++)
if (!entry->ptr) {
entry->key = key;
entry->ptr = ptr;
return;
}
std::cerr << "HSHMAX too low!" << std::endl;
exit(1);
}
void clear() { std::memset(table, 0, sizeof(table)); }
};
HashTable TBHash;
class TBFile : public std::ifstream { class TBFile : public std::ifstream {
std::string fname; std::string fname;
public: public:
// Open the file with the given name found among the TBPaths. TBPaths stores // Open the file with the given name found among the TBPaths. TBPaths stores
// the paths to directories where the .rtbw and .rtbz files can be found. // the paths to directories where the .rtbw and .rtbz files can be found.
@ -505,21 +541,6 @@ Key get_key(uint8_t* pcs, bool mirror)
return key; return key;
} }
void add_to_hash(TBEntry* ptr, Key key)
{
TBHashEntry* entry = TB_hash[key >> (64 - TBHASHBITS)];
for (int i = 0; i < HSHMAX && entry->ptr; i++, entry++) {}
if (!entry->ptr) {
entry->key = key;
entry->ptr = ptr;
} else {
std::cerr << "HSHMAX too low!" << std::endl;
exit(1);
}
}
void free_wdl_entry(TBEntry_piece* entry) void free_wdl_entry(TBEntry_piece* entry)
{ {
TBFile::unmap(entry->data, entry->mapping); TBFile::unmap(entry->data, entry->mapping);
@ -635,10 +656,10 @@ void init_tb(const std::vector<PieceType>& pieces)
entry->symmetric = (key1 == key2); entry->symmetric = (key1 == key2);
entry->has_pawns = hasPawns; entry->has_pawns = hasPawns;
add_to_hash(entry, key1); TBHash.insert(entry, key1);
if (key2 != key1) if (key2 != key1)
add_to_hash(entry, key2); TBHash.insert(entry, key2);
} }
uint64_t encode_piece(TBEntry_piece* ptr, uint8_t* norm, int* pos, int* factor) uint64_t encode_piece(TBEntry_piece* ptr, uint8_t* norm, int* pos, int* factor)
@ -1407,27 +1428,16 @@ uint8_t decompress_pairs(PairsData *d, uint64_t idx)
void load_dtz_table(const std::string& str, uint64_t key1, uint64_t key2) void load_dtz_table(const std::string& str, uint64_t key1, uint64_t key2)
{ {
int i;
TBEntry *ptr, *ptr3;
TBHashEntry *ptr2;
DTZ_table[0].key1 = key1; DTZ_table[0].key1 = key1;
DTZ_table[0].key2 = key2; DTZ_table[0].key2 = key2;
DTZ_table[0].entry = NULL; DTZ_table[0].entry = NULL;
// find corresponding WDL entry TBEntry* ptr = TBHash[key1];
ptr2 = TB_hash[key1 >> (64 - TBHASHBITS)];
for (i = 0; i < HSHMAX; i++) if (!ptr)
if (ptr2[i].key == key1)
break;
if (i == HSHMAX)
return; return;
ptr = ptr2[i].ptr; TBEntry* ptr3 = (TBEntry*)malloc(ptr->has_pawns
ptr3 = (TBEntry *)malloc(ptr->has_pawns
? sizeof(DTZEntry_pawn) ? sizeof(DTZEntry_pawn)
: sizeof(DTZEntry_piece)); : sizeof(DTZEntry_piece));
@ -1476,37 +1486,24 @@ std::string prt_str(Position& pos, bool mirror)
return s; return s;
} }
// probe_wdl_table and probe_dtz_table require similar adaptations.
int probe_wdl_table(Position& pos, int *success) int probe_wdl_table(Position& pos, int *success)
{ {
TBEntry *ptr;
TBHashEntry *ptr2;
uint64_t idx; uint64_t idx;
uint64_t key; int i, res;
int i;
uint8_t res;
int p[TBPIECES]; int p[TBPIECES];
// Obtain the position's material signature key. Key key = pos.material_key();
key = pos.material_key();
// Test for KvK. if (pos.count<ALL_PIECES>(WHITE) + pos.count<ALL_PIECES>(BLACK) == 2)
if (key == (Zobrist::psq[WHITE][KING][0] ^ Zobrist::psq[BLACK][KING][0])) return 0; // KvK
return 0;
ptr2 = TB_hash[key >> (64 - TBHASHBITS)]; TBEntry* ptr = TBHash[key];
for (i = 0; i < HSHMAX; i++) if (!ptr) {
if (ptr2[i].key == key)
break;
if (i == HSHMAX) {
*success = 0; *success = 0;
return 0; return 0;
} }
ptr = ptr2[i].ptr;
if (!ptr->ready) { if (!ptr->ready) {
TB_mutex.lock(); TB_mutex.lock();
@ -1514,7 +1511,7 @@ int probe_wdl_table(Position& pos, int *success)
std::string s = prt_str(pos, ptr->key != key); std::string s = prt_str(pos, ptr->key != key);
if (!init_table_wdl(ptr, s)) { if (!init_table_wdl(ptr, s)) {
ptr2[i].key = 0ULL; // Was ptr2->key = 0ULL; Just leave !ptr->ready condition
*success = 0; *success = 0;
TB_mutex.unlock(); TB_mutex.unlock();
return 0; return 0;
@ -1598,7 +1595,6 @@ int probe_wdl_table(Position& pos, int *success)
int probe_dtz_table(Position& pos, int wdl, int *success) int probe_dtz_table(Position& pos, int wdl, int *success)
{ {
TBEntry *ptr;
uint64_t idx; uint64_t idx;
int i, res; int i, res;
int p[TBPIECES]; int p[TBPIECES];
@ -1618,18 +1614,12 @@ int probe_dtz_table(Position& pos, int wdl, int *success)
DTZ_table[0] = table_entry; DTZ_table[0] = table_entry;
} else { } else {
TBHashEntry *ptr2 = TB_hash[key >> (64 - TBHASHBITS)]; TBEntry* ptr = TBHash[key];
if (!ptr) {
for (i = 0; i < HSHMAX; i++)
if (ptr2[i].key == key)
break;
if (i == HSHMAX) {
*success = 0; *success = 0;
return 0; return 0;
} }
ptr = ptr2[i].ptr;
bool mirror = (ptr->key != key); bool mirror = (ptr->key != key);
std::string s = prt_str(pos, mirror); std::string s = prt_str(pos, mirror);
@ -1643,7 +1633,7 @@ int probe_dtz_table(Position& pos, int wdl, int *success)
} }
} }
ptr = DTZ_table[0].entry; TBEntry* ptr = DTZ_table[0].entry;
if (!ptr) { if (!ptr) {
*success = 0; *success = 0;
@ -1825,7 +1815,7 @@ void Tablebases::init(const std::string& paths)
DTZ_table[i].entry = nullptr; DTZ_table[i].entry = nullptr;
} }
std::memset(TB_hash, 0, sizeof(TB_hash)); TBHash.clear();
TBnum_piece = TBnum_pawn = 0; TBnum_piece = TBnum_pawn = 0;
MaxCardinality = 0; MaxCardinality = 0;