summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/engine/ttable.h15
-rw-r--r--src/engine/ttable.c165
-rw-r--r--tests/generated.c18
3 files changed, 100 insertions, 98 deletions
diff --git a/include/engine/ttable.h b/include/engine/ttable.h
index 8b1938a..e1a10f1 100644
--- a/include/engine/ttable.h
+++ b/include/engine/ttable.h
@@ -5,9 +5,6 @@
#include "bitboard.h"
#include <stdatomic.h>
-#define TABLE_BITS 24
-#define TABLE_SIZE (1ULL << TABLE_BITS)
-#define TT_MASK (TABLE_SIZE - 1)
#define TT_BUCKET_SIZE 4
static struct zobrist_keys {
@@ -33,10 +30,13 @@ typedef struct {
typedef struct {
tentry_t entries[TT_BUCKET_SIZE];
- int items_filled;
+ // int items_filled;
} tbucket_t;
-typedef tbucket_t* ttable_t;
+typedef struct {
+ tbucket_t* buckets;
+ u64 mask;
+} ttable_t;
struct ttable_insert_args {
u64 key;
@@ -48,7 +48,10 @@ struct ttable_insert_args {
u8 flag;
};
-void ttable_init(ttable_t *table);
+// if you want size 8, then size_in_binary_log = 3
+// if you want size 4, then size_in_binary_log = 2
+// you are forced to have powers of 2 for size
+void ttable_init(ttable_t *table, size_t size_in_binary_log);
void ttable_deinit(ttable_t table);
void __ttable_insert(ttable_t table, struct ttable_insert_args args);
tentry_t *ttable_find(ttable_t table, u64 key);
diff --git a/src/engine/ttable.c b/src/engine/ttable.c
index 851e389..fc1b6f0 100644
--- a/src/engine/ttable.c
+++ b/src/engine/ttable.c
@@ -47,21 +47,28 @@ u64 zobrist_hash(position_t position) {
return output;
}
-void ttable_init(ttable_t *table) {
- ttable_t output = calloc(TABLE_SIZE, sizeof(tbucket_t));
- memcpy(table, &output, sizeof(output));
+void ttable_init(ttable_t *table, size_t size_in_binary_log) {
+ assert(size_in_binary_log < 64);
+ int size = 1ULL << size_in_binary_log;
+ table->buckets = calloc(size, sizeof(tbucket_t));
+ table->mask = size - 1;
}
void ttable_deinit(ttable_t table) {
- free(table);
+ free(table.buckets);
}
void __ttable_insert(ttable_t table, struct ttable_insert_args args) {
- tbucket_t *bucket = table + (args.key & TT_MASK);
+ tbucket_t *bucket = table.buckets + (args.key & table.mask);
tentry_t *best = bucket->entries;
- int count = bucket->items_filled;
- for (int i = 1; i < count; i++) {
+ int ci = 0;
+
+ for (int i = 0; i < TT_BUCKET_SIZE; i++) {
+ if (atomic_load(&bucket->entries[i].key) == args.key) {
+ best = bucket->entries + i;
+ break;
+ }
if (bucket->entries[i].depth >= best->depth) continue;
best = bucket->entries + i;
}
@@ -79,7 +86,7 @@ void __ttable_insert(ttable_t table, struct ttable_insert_args args) {
}
tentry_t *ttable_find(ttable_t table, u64 key) {
- tbucket_t *bucket = table + (key & TT_MASK);
+ tbucket_t *bucket = table.buckets + (key & table.mask);
for (int i = 0; i < TT_BUCKET_SIZE; i++) {
if (atomic_load(&(bucket->entries + i)->key) != key) continue;
@@ -91,20 +98,19 @@ tentry_t *ttable_find(ttable_t table, u64 key) {
#ifdef TEST_MOD
-bool test_empty_ttable() {
+bool test_ttable_empty() {
ttable_t table;
- ttable_init(&table);
+ ttable_init(&table, 4);
if (ttable_find(table, 123456789ULL) != NULL) return false;
ttable_deinit(table);
-
return true;
}
bool test_ttable_insert_and_find() {
ttable_t table;
- ttable_init(&table);
+ ttable_init(&table, 4);
u64 key = 0x123456789ABCDEF0ULL;
ttable_insert(table, .key = key, .depth = 8, .flag = TT_EXACT);
@@ -123,7 +129,7 @@ bool test_ttable_insert_and_find() {
bool test_ttable_wrong_key() {
ttable_t table;
- ttable_init(&table);
+ ttable_init(&table, 4);
u64 key = 0x123456789ABCDEF0ULL;
ttable_insert(table, .key = key, .depth = 8, .flag = TT_EXACT);
@@ -135,7 +141,7 @@ bool test_ttable_wrong_key() {
bool test_ttable_update_existing() {
ttable_t table;
- ttable_init(&table);
+ ttable_init(&table, 4);
u64 key = 987654321ULL;
ttable_insert(table, .key = key, .depth = 10, .flag = TT_LOWERBOUND);
@@ -151,77 +157,64 @@ bool test_ttable_update_existing() {
return true;
}
-// bool FAH_test_bucket_collision() {
-// ttable_t table;
-// ttable_init(&table);
-//
-//
-//
-// TranspositionTable tt;
-// tt_init(&tt, 1); // one bucket
-//
-// tt_store(&tt, 1, 10, 10, 5, TT_EXACT);
-// tt_store(&tt, 2, 20, 20, 5, TT_EXACT);
-// tt_store(&tt, 3, 30, 30, 5, TT_EXACT);
-// tt_store(&tt, 4, 40, 40, 5, TT_EXACT);
-//
-// assert(tt_probe(&tt, 1) != NULL);
-// assert(tt_probe(&tt, 2) != NULL);
-// assert(tt_probe(&tt, 3) != NULL);
-// assert(tt_probe(&tt, 4) != NULL);
-//
-// tt_destroy(&tt);
-// }
-
-// void test_replace_shallowest(void) {
-// TranspositionTable tt;
-// tt_init(&tt, 1);
-//
-// tt_store(&tt, 1, 0, 0, 10, TT_EXACT);
-// tt_store(&tt, 2, 0, 0, 20, TT_EXACT);
-// tt_store(&tt, 3, 0, 0, 30, TT_EXACT);
-// tt_store(&tt, 4, 0, 0, 40, TT_EXACT);
-//
-// // Bucket is full.
-//
-// tt_store(&tt, 5, 0, 0, 25, TT_EXACT);
-//
-// assert(tt_probe(&tt, 1) == NULL);
-//
-// assert(tt_probe(&tt, 2) != NULL);
-// assert(tt_probe(&tt, 3) != NULL);
-// assert(tt_probe(&tt, 4) != NULL);
-// assert(tt_probe(&tt, 5) != NULL);
-//
-// tt_destroy(&tt);
-// }
-
-// void test_many_entries(void)
-// {
-// TranspositionTable tt;
-// tt_init(&tt, 1 << 16);
-//
-// for (uint64_t i = 0; i < 50000; i++)
-// {
-// tt_store(&tt,
-// i * 7919,
-// i,
-// i,
-// i % 64,
-// TT_EXACT);
-// }
-//
-// for (uint64_t i = 0; i < 50000; i++)
-// {
-// TTEntry *e = tt_probe(&tt, i * 7919);
-//
-// if (e)
-// {
-// assert(e->key == i * 7919);
-// }
-// }
-//
-// tt_destroy(&tt);
-// }
+bool test_bucket_collision() {
+ ttable_t table;
+ ttable_init(&table, 2);
+
+ ttable_insert(table, .key = 1, .depth = 10, .flag = TT_EXACT);
+ ttable_insert(table, .key = 2, .depth = 20, .flag = TT_EXACT);
+ ttable_insert(table, .key = 3, .depth = 30, .flag = TT_EXACT);
+ ttable_insert(table, .key = 4, .depth = 40, .flag = TT_EXACT);
+
+ if (ttable_find(table, 1) == NULL) return false;
+ if (ttable_find(table, 2) == NULL) return false;
+ if (ttable_find(table, 3) == NULL) return false;
+ if (ttable_find(table, 4) == NULL) return false;
+
+ ttable_deinit(table);
+ return true;
+}
+
+bool test_ttable_replace_shallowest() {
+ ttable_t table;
+ ttable_init(&table, 0);
+
+ ttable_insert(table, .key = 1, .depth = 10, .flag = TT_EXACT);
+ ttable_insert(table, .key = 2, .depth = 20, .flag = TT_EXACT);
+ ttable_insert(table, .key = 3, .depth = 30, .flag = TT_EXACT);
+ ttable_insert(table, .key = 4, .depth = 40, .flag = TT_EXACT);
+
+ // Bucket is full.
+ ttable_insert(table, .key = 5, .depth = 25, .flag = TT_EXACT);
+
+ if (ttable_find(table, 1) != NULL) return false;
+
+ if (ttable_find(table, 2) == NULL) return false;
+ if (ttable_find(table, 3) == NULL) return false;
+ if (ttable_find(table, 4) == NULL) return false;
+ if (ttable_find(table, 5) == NULL) return false;
+
+ ttable_deinit(table);
+ return true;
+}
+
+bool test_ttable_many_entries() {
+ ttable_t table;
+ ttable_init(&table, 16);
+
+ for (u64 i = 0; i < 50000; i++) {
+ ttable_insert(table, .key = i * 7919, .depth = i % 64, .flag = TT_EXACT);
+ }
+
+ for (u64 i = 0; i < 50000; i++) {
+ tentry_t *e = ttable_find(table, i * 7919);
+
+ if (e == NULL) continue;
+ if (e->key != i * 7919) return false;
+ }
+
+ ttable_deinit(table);
+ return true;
+}
#endif
diff --git a/tests/generated.c b/tests/generated.c
index 7de9c24..a605554 100644
--- a/tests/generated.c
+++ b/tests/generated.c
@@ -4,15 +4,18 @@
#include "../src/engine/moves/king.c"
#include "../src/uci/command.c"
-int total_test_count = 14;
-bool (*tests[14])(void) = {
+int total_test_count = 17;
+bool (*tests[17])(void) = {
test_fen_no_passant,
test_fen_passant,
test_starting_position,
- test_empty_ttable,
+ test_ttable_empty,
test_ttable_insert_and_find,
test_ttable_wrong_key,
test_ttable_update_existing,
+ test_bucket_collision,
+ test_ttable_replace_shallowest,
+ test_ttable_many_entries,
test_perft_starting_position,
test_perft_kiwipete_position,
test_perft_position3,
@@ -22,15 +25,18 @@ bool (*tests[14])(void) = {
test_invalid_cmd_uci_cmd_t,
};
-int max_test_name_size = 23;
-char test_names[14][100] = {
+int max_test_name_size = 25;
+char test_names[17][100] = {
"fen_no_passant",
"fen_passant",
"starting_position",
- "empty_ttable",
+ "ttable_empty",
"ttable_insert_and_find",
"ttable_wrong_key",
"ttable_update_existing",
+ "bucket_collision",
+ "ttable_replace_shallowest",
+ "ttable_many_entries",
"perft_starting_position",
"perft_kiwipete_position",
"perft_position3",