rename TT funcs to TT_xxx()

This commit is contained in:
2024-06-12 07:50:19 +02:00
parent ec2d2291d4
commit 8be03c6230
5 changed files with 171 additions and 21 deletions

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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);
} }

View File

@@ -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);
} }