rename TT funcs to TT_xxx()
This commit is contained in:
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
#include "brlib.h" /* brlib types */
|
#include "brlib.h" /* brlib types */
|
||||||
|
|
||||||
#define ONE 1ull
|
#define ONE 1ul
|
||||||
#define U64(const_u64) const_u64##ULL
|
#define U64(const_u64) const_u64##UL
|
||||||
#define BIT(i) ( (u64) (ONE << (i)) )
|
#define BIT(i) ( (u64) (ONE << (i)) )
|
||||||
|
|
||||||
#define BOARDSIZE (8*8)
|
#define BOARDSIZE (8*8)
|
||||||
@@ -176,7 +176,7 @@ s64 clock_elapsed_μs(mclock_t *clock);
|
|||||||
s64 clock_elapsed_ms(mclock_t *clock);
|
s64 clock_elapsed_ms(mclock_t *clock);
|
||||||
double clock_elapsed_sec(mclock_t *clock);
|
double clock_elapsed_sec(mclock_t *clock);
|
||||||
|
|
||||||
#define RAND_SEED_DEFAULT U64(1)
|
#define RAND_SEED_DEFAULT U64(0xb0d1ccea)
|
||||||
|
|
||||||
void rand_init(u64 seed);
|
void rand_init(u64 seed);
|
||||||
u64 rand64(void);
|
u64 rand64(void);
|
||||||
|
144
src/hash.c
144
src/hash.c
@@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include <brlib.h>
|
#include <brlib.h>
|
||||||
#include <bitops.h>
|
#include <bitops.h>
|
||||||
@@ -99,9 +100,17 @@ hkey_t zobrist_calc(pos_t *pos)
|
|||||||
* @return: True if Zobrist key is OK.
|
* @return: True if Zobrist key is OK.
|
||||||
*/
|
*/
|
||||||
#ifdef ZOBRIST_VERIFY
|
#ifdef ZOBRIST_VERIFY
|
||||||
|
|
||||||
|
#pragma push_macro("BUG_ON") /* force BUG_ON and WARN_ON */
|
||||||
|
#pragma push_macro("WARN_ON")
|
||||||
|
#undef BUG_ON
|
||||||
|
#define BUG_ON
|
||||||
|
#undef WARN_ON
|
||||||
|
#define WARN_ON
|
||||||
|
|
||||||
bool zobrist_verify(pos_t *pos)
|
bool zobrist_verify(pos_t *pos)
|
||||||
{
|
{
|
||||||
key_t diff, key = zobrist_calc(pos);
|
hkey_t diff, key = zobrist_calc(pos);
|
||||||
|
|
||||||
if (pos->key == key)
|
if (pos->key == key)
|
||||||
return true;
|
return true;
|
||||||
@@ -120,17 +129,19 @@ bool zobrist_verify(pos_t *pos)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (castle_rights_t c = CASTLE_NONE; c <= CASTLE_ALL; ++c)
|
for (castle_rights_t c = CASTLE_NONE; c <= CASTLE_ALL; ++c) {
|
||||||
if (diff == zobrist_castling[c]) {
|
if (diff == zobrist_castling[c]) {
|
||||||
warn(true, "zobrist difference is castling:[%d]\n", c);
|
warn(true, "zobrist difference is castling:[%d]\n", c);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (file_t f = FILE_A; f <= FILE_H; ++f)
|
for (file_t f = FILE_A; f <= FILE_H; ++f) {
|
||||||
if (diff == zobrist_ep[f]) {
|
if (diff == zobrist_ep[f]) {
|
||||||
warn(true, "zobrist difference is ep:[%d]\n", f);
|
warn(true, "zobrist difference is ep:[%d]\n", f);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (diff == zobrist_turn) {
|
if (diff == zobrist_turn) {
|
||||||
warn(true, "zobrist difference is turn\n");
|
warn(true, "zobrist difference is turn\n");
|
||||||
goto end;
|
goto end;
|
||||||
@@ -138,11 +149,16 @@ bool zobrist_verify(pos_t *pos)
|
|||||||
warn(true, "zobrist diff %lx is unknown\n", diff);
|
warn(true, "zobrist diff %lx is unknown\n", diff);
|
||||||
end:
|
end:
|
||||||
bug_on(false);
|
bug_on(false);
|
||||||
|
/* not reached */
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
#pragma pop_macro("WARN_ON")
|
||||||
|
#pragma pop_macro("BUG_ON")
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hash_create() - hashtable creation.
|
* tt_create() - create transposition table
|
||||||
* @sizemb: s32 size of hash table in Mb
|
* @sizemb: s32 size of hash table in Mb
|
||||||
*
|
*
|
||||||
* Create a hash table of max @sizemb (or HASH_SIZE_MBif @sizemb <= 0) Mb size.
|
* Create a hash table of max @sizemb (or HASH_SIZE_MBif @sizemb <= 0) Mb size.
|
||||||
@@ -164,7 +180,7 @@ end:
|
|||||||
* @return: hash table size in Mb. If memory allocation fails, the function does
|
* @return: hash table size in Mb. If memory allocation fails, the function does
|
||||||
* not return.
|
* not return.
|
||||||
*/
|
*/
|
||||||
int hash_create(s32 sizemb)
|
int tt_create(s32 sizemb)
|
||||||
{
|
{
|
||||||
size_t bytes, target_nbuckets;
|
size_t bytes, target_nbuckets;
|
||||||
u32 nbits;
|
u32 nbits;
|
||||||
@@ -185,7 +201,7 @@ int hash_create(s32 sizemb)
|
|||||||
|
|
||||||
if (hash_tt.nbits != nbits) {
|
if (hash_tt.nbits != nbits) {
|
||||||
if (hash_tt.nbits)
|
if (hash_tt.nbits)
|
||||||
hash_delete();
|
tt_delete();
|
||||||
|
|
||||||
hash_tt.nbits = nbits;
|
hash_tt.nbits = nbits;
|
||||||
|
|
||||||
@@ -207,17 +223,17 @@ int hash_create(s32 sizemb)
|
|||||||
// printf("unchanged (cleared)\n");
|
// printf("unchanged (cleared)\n");
|
||||||
//}
|
//}
|
||||||
/* attention - may fail ! */
|
/* attention - may fail ! */
|
||||||
hash_clear();
|
tt_clear();
|
||||||
|
|
||||||
return hash_tt.nbits;
|
return hash_tt.nbits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hash_clear() - clear hashtable data.
|
* tt_clear() - clear transposition table
|
||||||
*
|
*
|
||||||
* Reset hashtable entries (if available) and statistic information.
|
* Reset hashtable entries (if available) and statistic information.
|
||||||
*/
|
*/
|
||||||
void hash_clear()
|
void tt_clear()
|
||||||
{
|
{
|
||||||
if (hash_tt.keys)
|
if (hash_tt.keys)
|
||||||
memset(hash_tt.keys, 0, hash_tt.bytes);
|
memset(hash_tt.keys, 0, hash_tt.bytes);
|
||||||
@@ -228,13 +244,119 @@ void hash_clear()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hash_delete() - delete hashtable data.
|
* tt_delete() - delete transposition table
|
||||||
*
|
*
|
||||||
* free hashtable data.
|
* free hashtable data.
|
||||||
*/
|
*/
|
||||||
void hash_delete()
|
void tt_delete()
|
||||||
{
|
{
|
||||||
if (hash_tt.keys)
|
if (hash_tt.keys)
|
||||||
safe_free(hash_tt.keys);
|
safe_free(hash_tt.keys);
|
||||||
memset(&hash_tt, 0, sizeof(hash_tt));
|
memset(&hash_tt, 0, sizeof(hash_tt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tt_probe() - probe tt for an entry
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
hentry_t *tt_probe(hkey_t key)
|
||||||
|
{
|
||||||
|
bucket_t *bucket;
|
||||||
|
hentry_t *entry;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
bug_on(!hash_tt.keys);
|
||||||
|
bucket = hash_tt.keys + (key & hash_tt.mask);
|
||||||
|
|
||||||
|
/* find key in buckets */
|
||||||
|
for (i = 0; i < NBUCKETS; ++i) {
|
||||||
|
entry = bucket->entry + i;
|
||||||
|
if (key == entry->key)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < NBUCKETS)
|
||||||
|
return entry;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tt_probe_perft() - probe tt for an entry (perft version)
|
||||||
|
* @key: Zobrist (hkey_t) key
|
||||||
|
* @depth: depth from search root
|
||||||
|
*
|
||||||
|
* Search transposition for @key entry with @depth depth.
|
||||||
|
*
|
||||||
|
* @return: @hentry_t address is found, TT_MISS otherwise.
|
||||||
|
*/
|
||||||
|
hentry_t *tt_probe_perft(const hkey_t key, const u16 depth)
|
||||||
|
{
|
||||||
|
bucket_t *bucket;
|
||||||
|
hentry_t *entry;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
bug_on(!hash_tt.keys);
|
||||||
|
bucket = hash_tt.keys + (key & hash_tt.mask);
|
||||||
|
|
||||||
|
/* find key in buckets */
|
||||||
|
for (i = 0; i < NBUCKETS; ++i) {
|
||||||
|
entry = bucket->entry + i;
|
||||||
|
if (key == entry->key && HASH_PERFT_DEPTH(entry->data) == depth) {
|
||||||
|
printf("tt hit: key=%lx bucket=%lu entry=%d!\n",
|
||||||
|
key, bucket - hash_tt.keys, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < NBUCKETS)
|
||||||
|
return entry;
|
||||||
|
printf("tt miss: key=%lx bucket=%lu\n",
|
||||||
|
key, bucket - hash_tt.keys);
|
||||||
|
return TT_MISS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tt_store_perft() - store a transposition table entry (perft version)
|
||||||
|
* @key: Zobrist (hkey_t) key
|
||||||
|
* @depth: depth from search root
|
||||||
|
* @nodes: value to store
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
hentry_t *tt_store_perft(const hkey_t key, const u16 depth, const u64 nodes)
|
||||||
|
{
|
||||||
|
bucket_t *bucket;
|
||||||
|
hentry_t *entry;
|
||||||
|
int replace = -1, i;
|
||||||
|
// uint mindepth = 0;
|
||||||
|
u64 data = HASH_PERFT(depth, nodes);
|
||||||
|
printf("tt_store: key=%lx data=%lx depth=%d=%d nodes=%lu=%lu\n",
|
||||||
|
key, data, depth, HASH_PERFT_DEPTH(data), nodes, HASH_PERFT_VAL(data));
|
||||||
|
bug_on(!hash_tt.keys);
|
||||||
|
bucket = hash_tt.keys + (key & hash_tt.mask);
|
||||||
|
|
||||||
|
/* find key in buckets */
|
||||||
|
for (i = 0; i < NBUCKETS; ++i) {
|
||||||
|
entry = bucket->entry + i;
|
||||||
|
if (!entry->key) {
|
||||||
|
replace = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* else {
|
||||||
|
* /\* we replace hash if we are higher in tree *\/
|
||||||
|
* if (key == entry->key && HASH_PERFT_DEPTH(entry->data) > mindepth) {
|
||||||
|
* mindepth = HASH_PERFT_DEPTH(entry->data);
|
||||||
|
* replace = i;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
if (replace >= 0) {
|
||||||
|
printf("replacing key=%lx=%lx bucket=%lu idx=%d val=%lu\n",
|
||||||
|
key, entry->key, bucket - hash_tt.keys, replace, nodes);
|
||||||
|
entry = bucket->entry + replace;
|
||||||
|
entry->key = key;
|
||||||
|
entry->data = data;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
38
src/hash.h
38
src/hash.h
@@ -14,7 +14,7 @@
|
|||||||
#ifndef HASH_H
|
#ifndef HASH_H
|
||||||
#define HASH_H
|
#define HASH_H
|
||||||
|
|
||||||
#include <assert.h>
|
#include <bug.h>
|
||||||
|
|
||||||
#include "chessdefs.h"
|
#include "chessdefs.h"
|
||||||
|
|
||||||
@@ -24,6 +24,8 @@
|
|||||||
#define HASH_SIZE_MIN 4
|
#define HASH_SIZE_MIN 4
|
||||||
#define HASH_SIZE_MAX 32768 /* 32Gb */
|
#define HASH_SIZE_MAX 32768 /* 32Gb */
|
||||||
|
|
||||||
|
#define TT_MISS NULL
|
||||||
|
|
||||||
typedef u64 hkey_t; /* cannot use typedef for key_t */
|
typedef u64 hkey_t; /* cannot use typedef for key_t */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,8 +48,18 @@ typedef struct {
|
|||||||
};
|
};
|
||||||
} hentry_t;
|
} hentry_t;
|
||||||
|
|
||||||
|
/* hentry perft data:
|
||||||
|
* 0-47: perft value
|
||||||
|
* 48-63: depth
|
||||||
|
*/
|
||||||
|
#define HASH_PERFT_MASK U64(0xffffffffffff)
|
||||||
|
#define HASH_PERFT(depth, val) ((((u64) depth) << 48) | ((val) & HASH_PERFT_MASK))
|
||||||
|
#define HASH_PERFT_VAL(data) ((data) & HASH_PERFT_MASK)
|
||||||
|
#define HASH_PERFT_DEPTH(data) ((u16)((data) >> 48))
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
hentry_t buckets[NBUCKETS];
|
hentry_t entry[NBUCKETS];
|
||||||
} bucket_t;
|
} bucket_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -97,8 +109,24 @@ bool zobrist_verify(pos_t *pos);
|
|||||||
#define zobrist_verify(p) true
|
#define zobrist_verify(p) true
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int hash_create(int Mb);
|
/**
|
||||||
void hash_clear(void);
|
* tt_prefetch() - prefetch hash table entry
|
||||||
void hash_delete(void);
|
* @hash: u64 key
|
||||||
|
*
|
||||||
|
* Prefetch memory for @key.
|
||||||
|
*/
|
||||||
|
static inline void tt_prefetch(hkey_t key)
|
||||||
|
{
|
||||||
|
bug_on(!hash_tt.keys);
|
||||||
|
__builtin_prefetch(hash_tt.keys + (key & hash_tt.mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
int tt_create(int Mb);
|
||||||
|
void tt_clear(void);
|
||||||
|
void tt_delete(void);
|
||||||
|
|
||||||
|
hentry_t *tt_probe(hkey_t key);
|
||||||
|
hentry_t *tt_probe_perft(const hkey_t key, const u16 depth);
|
||||||
|
hentry_t *tt_store_perft(const hkey_t key, const u16 depth, const u64 nodes);
|
||||||
|
|
||||||
#endif /* HASH_H */
|
#endif /* HASH_H */
|
||||||
|
@@ -37,6 +37,6 @@ void init_all(void)
|
|||||||
|
|
||||||
/* zobrist tables & default tt hashtable */
|
/* zobrist tables & default tt hashtable */
|
||||||
zobrist_init();
|
zobrist_init();
|
||||||
hash_create(HASH_SIZE_DEFAULT);
|
tt_create(HASH_SIZE_DEFAULT);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -59,7 +59,7 @@ int main(int __unused ac, __unused char**av)
|
|||||||
//fflush(stdout);
|
//fflush(stdout);
|
||||||
if (!pos_ok(pos, false)) {
|
if (!pos_ok(pos, false)) {
|
||||||
printf("*** fen %d [%s] move %d [%s] invalid position after move_do\n",
|
printf("*** fen %d [%s] move %d [%s] invalid position after move_do\n",
|
||||||
test_line, fen, j, move_str(movebuf, *move, 0));
|
test_line, fen, j, move_to_str(movebuf, *move, 0));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user