add info in pos_print, start perft TT testing

This commit is contained in:
2024-06-13 10:28:32 +02:00
parent 8be03c6230
commit 148fef20ea
9 changed files with 310 additions and 49 deletions

View File

@@ -206,7 +206,7 @@ int tt_create(s32 sizemb)
hash_tt.nbits = nbits;
hash_tt.nbuckets = BIT(hash_tt.nbits);
hash_tt.nkeys = hash_tt.nbuckets * NBUCKETS;
hash_tt.nkeys = hash_tt.nbuckets * ENTRIES_PER_BUCKET;
hash_tt.bytes = hash_tt.nbuckets * sizeof(bucket_t);
hash_tt.mb = hash_tt.bytes / 1024 / 1024;
@@ -238,9 +238,10 @@ void tt_clear()
if (hash_tt.keys)
memset(hash_tt.keys, 0, hash_tt.bytes);
hash_tt.used_buckets = 0;
hash_tt.used_keys = 0;
hash_tt.collisions = 0;
hash_tt.hits = 0;
hash_tt.misses = 0;
}
/**
@@ -270,12 +271,12 @@ hentry_t *tt_probe(hkey_t key)
bucket = hash_tt.keys + (key & hash_tt.mask);
/* find key in buckets */
for (i = 0; i < NBUCKETS; ++i) {
for (i = 0; i < ENTRIES_PER_BUCKET; ++i) {
entry = bucket->entry + i;
if (key == entry->key)
break;
}
if (i < NBUCKETS)
if (i < ENTRIES_PER_BUCKET)
return entry;
return NULL;
}
@@ -299,18 +300,18 @@ hentry_t *tt_probe_perft(const hkey_t key, const u16 depth)
bucket = hash_tt.keys + (key & hash_tt.mask);
/* find key in buckets */
for (i = 0; i < NBUCKETS; ++i) {
for (i = 0; i < ENTRIES_PER_BUCKET; ++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;
hash_tt.hits++;
//printf("tt hit: key=%lx bucket=%lu entry=%d!\n",
// key, bucket - hash_tt.keys, i);
return entry;
}
}
if (i < NBUCKETS)
return entry;
printf("tt miss: key=%lx bucket=%lu\n",
key, bucket - hash_tt.keys);
//printf("tt miss: key=%lx bucket=%lu\n",
// key, bucket - hash_tt.keys);
hash_tt.misses++;
return TT_MISS;
}
@@ -325,24 +326,36 @@ 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;
int replace = -1, newkey = 0;
uint mindepth = 1024;
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));
//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));
printf("tt_store: key=%lx depth=%d nodes=%lu ",
key, depth, nodes);
bug_on(!hash_tt.keys);
bucket = hash_tt.keys + (key & hash_tt.mask);
/* find key in buckets */
for (i = 0; i < NBUCKETS; ++i) {
for (int i = 0; i < ENTRIES_PER_BUCKET; ++i) {
entry = bucket->entry + i;
if (key == entry->key && HASH_PERFT_DEPTH(entry->data)) {
printf("tt_store: sup key/depth, this should not happen!\n");
return NULL;
}
if (!entry->key) {
replace = i;
break;
}
/* we replace hash if we are higher in tree */
if (HASH_PERFT_DEPTH(entry->data) < mindepth) {
mindepth = HASH_PERFT_DEPTH(entry->data);
replace = i;
}
/*
* 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;
@@ -351,12 +364,32 @@ hentry_t *tt_store_perft(const hkey_t key, const u16 depth, const u64 nodes)
*/
}
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;
if (HASH_PERFT_VAL(entry->data)) {
printf("REPL entry=%lu[%d] key=%lx->%lx val=%lu->%lu\n",
bucket - hash_tt.keys, replace,
entry->key, key,
HASH_PERFT_VAL(entry->data), nodes);
} else {
printf("NEW entry=%lu[%d] key=%lx val=%lu\n",
bucket - hash_tt.keys, replace,
entry->key, nodes);
}
entry->key = key;
entry->data = data;
return entry;
} else {
printf("TT full, skip\n");
}
return NULL;
}
void tt_stats()
{
printf("TT: sz=%u bits=%u bcks=%'lu entries=%'lu mask=%10x"
"used=%lu hits/miss=%'lu/%'lu\n",
hash_tt.mb, hash_tt.nbits, hash_tt.nbuckets, hash_tt.nkeys, hash_tt.mask,
hash_tt.used_keys, hash_tt.hits, hash_tt.misses);
//printf("\tused=%lu hits/miss=%lu/%lu\n",
// hash_tt.used_keys, hash_tt.hits, hash_tt.misses);
}

View File

@@ -18,7 +18,7 @@
#include "chessdefs.h"
#define NBUCKETS 4 /* buckets per hash table entry */
#define ENTRIES_PER_BUCKET 4 /* buckets per hash table entry */
#define HASH_SIZE_DEFAULT 32 /* default: 32Mb */
#define HASH_SIZE_MIN 4
@@ -35,7 +35,7 @@ typedef u64 hkey_t; /* cannot use typedef for key_
* 16 bytes in future, it should be updated to be exactly 32 bytes.
*/
typedef struct {
hkey_t key; /* zobrist */
hkey_t key; /* zobrist */
union {
u64 data;
struct {
@@ -59,7 +59,7 @@ typedef struct {
typedef struct {
hentry_t entry[NBUCKETS];
hentry_t entry[ENTRIES_PER_BUCKET];
} bucket_t;
typedef struct {
@@ -78,9 +78,11 @@ typedef struct {
u32 mask; /* nbuckets - 1, key mask */
/* stats - unsure about usage */
size_t used_buckets;
//size_t used_buckets;
size_t used_keys;
u64 collisions;
u64 hits;
u64 misses;
} hasht_t;
/* hack:
@@ -128,5 +130,6 @@ 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);
void tt_stats(void);
#endif /* HASH_H */

View File

@@ -108,7 +108,8 @@ pos_t *move_do(pos_t *pos, const move_t move, state_t *state)
}
} else if (is_enpassant(move)) { /* clear grabbed pawn */
square_t grabbed = to - up;
key ^= zobrist_pieces[pos->board[grabbed]][grabbed];
piece_t pc = pos->board[grabbed];
key ^= zobrist_pieces[pc][grabbed];
pos_clr_sq(pos, grabbed);
}
}

View File

@@ -429,9 +429,10 @@ void pos_print(const pos_t *pos)
char str[128];
board_print(pos->board);
printf("fen %s\n", pos2fen(pos, str));
printf("checkers: %s\n", pos_checkers2str(pos, str, sizeof(str)));
printf("pinners : %s\n", pos_pinners2str(pos, str, sizeof(str)));
printf("key:%lx ", pos->key);
printf("fen: %s\n", pos2fen(pos, str));
printf("checkers:%s ", pos_checkers2str(pos, str, sizeof(str)));
printf("pinners: %s ", pos_pinners2str(pos, str, sizeof(str)));
printf("blockers: %s\n", pos_blockers2str(pos, str, sizeof(str)));
}

View File

@@ -43,13 +43,16 @@
*/
u64 perft(pos_t *pos, int depth, int ply, bool output)
{
int subnodes;
u64 nodes = 0;
static movelist_t stack;
//int subnodes;
u64 subnodes, nodes = 0;
movelist_t movelist;
move_t *move, *last;
state_t state;
movelist.nmoves = 0;
if (ply == 1)
stack.nmoves = 0;
pos_set_checkers_pinners_blockers(pos);
pos_legal(pos, pos_gen_pseudo(pos, &movelist));
@@ -59,19 +62,46 @@ u64 perft(pos_t *pos, int depth, int ply, bool output)
nodes++;
} else {
move_do(pos, *move, &state);
stack.move[stack.nmoves++] = *move;
if (ply == 2 &&
//move_from(*move) == F7 &&
//move_to(*move) == F5 &&
move_from(stack.move[stack.nmoves-2]) == B2 &&
move_to(stack.move[stack.nmoves-2]) == B4 &&
move_from(stack.move[stack.nmoves-1]) == F7 &&
move_to(stack.move[stack.nmoves-1]) == F5
) {
//&& pos->board[F5] == B_PAWN) {
moves_print(&stack, 0);
pos_print(pos);
}
if (depth == 2) {
movelist_t movelist2;
pos_set_checkers_pinners_blockers(pos);
subnodes = pos_legal(pos, pos_gen_pseudo(pos, &movelist2))->nmoves;
} else {
subnodes = perft(pos, depth - 1, ply + 1, output);
hentry_t *entry;
//if (ply >= 4 && ply <= 8) {
if (ply == 4) {
if ((entry = tt_probe_perft(pos->key, depth))) {
subnodes = HASH_PERFT_VAL(entry->data);
printf("tt hit key=%lx ply=%d depth=%d nodes=%lu\n",
pos->key, ply, depth, subnodes);
} else {
subnodes = perft(pos, depth - 1, ply + 1, output);
tt_store_perft(pos->key, depth, subnodes);
}
} else {
subnodes = perft(pos, depth - 1, ply + 1, output);
}
}
if (output && ply == 1) {
char movestr[8];
printf("%s: %d\n", move_str(movestr, *move, 0), subnodes);
printf("%s: %lu\n", move_to_str(movestr, *move, 0), subnodes);
}
nodes += subnodes;
move_undo(pos, *move, &state);
stack.nmoves--;
}
}
@@ -99,7 +129,7 @@ u64 perft_alt(pos_t *pos, int depth, int ply, bool output)
move_t *move, *last;
state_t state;
movelist.nmoves = 0;
//movelist.nmoves = 0;
pos_set_checkers_pinners_blockers(pos);
state = pos->state;
@@ -119,7 +149,7 @@ u64 perft_alt(pos_t *pos, int depth, int ply, bool output)
}
if (output && ply == 1) {
char movestr[8];
printf("%s: %d\n", move_str(movestr, *move, 0), subnodes);
printf("%s: %d\n", move_to_str(movestr, *move, 0), subnodes);
}
nodes += subnodes;
move_undo_alt(pos, *move);