stellarUCI Chess engine written in C++20 |
git clone git://git.dimitrijedobrota.com/stellar.git |
Log | Files | Refs | README | LICENSE | |
commit | 1ecc793cac68e9c8768895ee4d358cb6b3ce1c31 |
parent | eb0c42bd2bf2f52666067bf7f1fad41dfe4948a9 |
author | Dimitrije Dobrota <mail@dimitrijedobrota.com> |
date | Fri, 28 Jul 2023 13:28:19 +0200 |
Add Multithreaded PERFT
Diffstat:M | src/engine.c | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- |
1 files changed, 92 insertions(+), 27 deletions(-)
diff --git a/src/engine.c b/src/engine.c
@@ -826,9 +826,9 @@ void uci_loop(void) {
struct MoveList_T moveList[10];
long nodes;
void perft_driver(CBoard_T board, int depth) {
void perft_driver(CBoard_T board, struct MoveList_T *moveList, int depth, unsigned long long *nodes) {
if (depth == 0) {
nodes++;
(*nodes)++;
return;
}
@@ -839,8 +839,9 @@ void perft_driver(CBoard_T board, int depth) {
CBoard_copy(board, copy);
if (!Move_make(MoveList_move(list, i), copy, 0))
continue;
perft_driver(copy, depth - 1);
perft_driver(copy, moveList, depth - 1, nodes);
}
MoveList_reset(list);
CBoard_free(©);
}
@@ -856,24 +857,96 @@ void perft_test(CBoard_T board, int depth) {
for (int i = 0; i < MoveList_size(list); i++) {
CBoard_copy(board, copy);
Move move = MoveList_move(list, i);
if (!Move_make(MoveList_move(list, i), copy, 0))
continue;
long cummulative_nodes = nodes;
perft_driver(copy, depth - 1);
long old_nodes = nodes - cummulative_nodes;
printf("%s%s: %ld\n", square_to_coordinates[Move_source(move)],
square_to_coordinates[Move_target(move)], old_nodes);
if (!Move_make(MoveList_move(list, i), copy, 0)) continue;
unsigned long long node = 0;
perft_driver(copy, moveList, depth - 1, &node);
printf("%s%s: %llu\n", square_to_coordinates[Move_source(move)],
square_to_coordinates[Move_target(move)], node);
nodes+=node;
}
MoveList_reset(list);
CBoard_free(©);
printf("\nNodes searched: %ld\n\n", nodes);
return;
printf("\n Depth: %d\n", depth);
printf(" Nodes: %ld\n", nodes);
printf(" Time: %ld\n\n", get_time_ms() - start);
}
#include <semaphore.h>
#include <pthread.h>
typedef struct perf_shared perf_shared;
struct perf_shared {
CBoard_T board;
MoveList_T list;
int depth;
sem_t* mutex;
int* index;
sem_t* finish;
unsigned long long *total;
};
void* perft_thread(void *arg) {
perf_shared *shared = (perf_shared *)arg;
CBoard_T board = CBoard_new();
unsigned long long node_count = 0;
struct MoveList_T moveList[10];
while(1) {
sem_wait(shared->mutex);
*shared->total += node_count;
if(*shared->index >= MoveList_size(shared->list)) {
sem_post(shared->mutex);
break;
}
Move move = MoveList_move(shared->list, (*shared->index)++);
sem_post(shared->mutex);
CBoard_copy(shared->board, board);
if(!Move_make(move, board, 0)) continue;
node_count = 0;
perft_driver(board, moveList, shared->depth, &node_count);
printf("%s%s: %llu\n", square_to_coordinates[Move_source(move)],
square_to_coordinates[Move_target(move)], node_count);
}
CBoard_free(&board);
sem_post(shared->finish);
return NULL;
}
void perft_test_threaded(CBoard_T board, int depth) {
MoveList_T list = MoveList_generate(NULL, board);
int size = 8;
unsigned long long total = 0;
perf_shared shared[size];
pthread_t threads[size];
sem_t mutex, finish;
int index = 0;
sem_init(&mutex, 0, 1);
sem_init(&finish, 0, 0);
for(int i=0; i<size; i++) {
shared[i].board = board;
shared[i].list = list;
shared[i].depth = depth - 1;
shared[i].mutex = &mutex;
shared[i].index = &index;
shared[i].finish = &finish;
shared[i].total = &total;
pthread_create(threads + i, NULL, perft_thread, (void *)(shared + i));
}
for(int i=0; i<size; i++) sem_wait(&finish);
MoveList_free(&list);
printf("Nodes processed: %llu\n", total);
}
/* MAIN */
void init_all() {
@@ -881,23 +954,15 @@ void init_all() {
init_sliders_attacks();
}
int main(void) {
init_all();
int debug = 1;
if (debug) {
CBoard_T board = NULL;
MoveList_T list = NULL;
Instruction_T inst = NULL;
(void)inst;
(void)list;
board = CBoard_fromFEN(board, tricky_position);
CBoard_print(board);
/* MoveList_print(MoveList_generate(NULL, board)); */
perft_test(board, 5);
/* search_position(board, 5); */
CBoard_free(&board);
} else
uci_loop();
CBoard_T board = NULL;
board = CBoard_fromFEN(board, start_position);
CBoard_print(board);
//perft_test(board, 7);
perft_test_threaded(board, 7);
CBoard_free(&board);
return 0;
}