ref: 91e6d5fba63d1e68d751c0fc7823838afa7b7756
parent: d39b1d1ceed402163d8e61822269cb87e3b6f879
author: zamfofex <zamfofex@twdb.moe>
date: Sat Jan 4 09:20:28 EST 2025
improve memory handling
--- a/search.c
+++ b/search.c
@@ -70,10 +70,14 @@
_Atomic int stop;
};
-struct moonfish_data {+struct moonfish_thread {+#ifndef moonfish_no_threads
+ thrd_t thread;
+#endif
struct moonfish_root *root;
unsigned long int time, time0;
long int node_count;
+ unsigned char clean;
};
static short int moonfish_values0[] = {0, 0, 0, 0, 56, 96, 84, 65, 61, 92, 74, 79, 58, 88, 83, 95, 69, 102, 96, 115, 82, 132, 156, 159, 258, 226, 262, 274, 0, 0, 0, 0, 262, 317, 317, 310, 323, 314, 337, 344, 321, 350, 356, 367, 341, 370, 371, 371, 366, 368, 406, 398, 361, 399, 433, 442, 338, 329, 420, 402, 194, 295, 237, 363, 356, 375, 360, 346, 382, 394, 396, 378, 386, 393, 387, 395, 382, 390, 392, 414, 380, 397, 421, 430, 406, 429, 426, 440, 374, 391, 413, 395, 343, 339, 291, 298, 456, 467, 469, 477, 427, 460, 462, 465, 440, 462, 447, 458, 447, 457, 454, 469, 474, 484, 496, 513, 491, 529, 533, 548, 523, 521, 552, 552, 564, 550, 535, 552, 1046, 1032, 1038, 1058, 1046, 1062, 1070, 1058, 1049, 1063, 1056, 1052, 1047, 1056, 1051, 1046, 1073, 1053, 1058, 1057, 1078, 1083, 1077, 1071, 1049, 1001, 1063, 1041, 1057, 1071, 1089, 1107, 20, 37, -21, -15, 18, 4, -61, -82, -63, -50, -84, -97, -93, -68, -82, -97, -77, -40, -24, -40, -31, 28, 52, 36, 44, 13, 53, 63, 163, 141, 61, 70};@@ -123,9 +127,23 @@
static void moonfish_discard(struct moonfish_node *node)
{- int i;
- for (i = 0 ; i < node->count ; i++) moonfish_discard(node->children + i);
- if (node->count > 0) free(node->children);
+ short int i, count;
+
+#ifdef moonfish_no_threads
+ count = node->count;
+ if (count <= 0) return;
+#else
+ for (;;) {+ count = node->count;
+ if (count == -1) continue;
+ if (count <= 0) return;
+ if (atomic_compare_exchange_strong(&node->count, &count, -1)) break;
+ }
+#endif
+
+ for (i = 0 ; i < count ; i++) moonfish_discard(node->children + i);
+ free(node->children);
+ node->count = 0;
}
static void moonfish_node(struct moonfish_node *node)
@@ -222,13 +240,13 @@
{struct moonfish_node *next;
float max_confidence, confidence;
- int i;
- short int n;
+ short int i, n;
for (;;) {#ifdef moonfish_no_threads
- if (node->count <= 0) break;
+ n = node->count;
+ if (n <= 0) break;
#else
n = 0;
if (atomic_compare_exchange_strong(&node->count, &n, -1)) break;
@@ -239,7 +257,7 @@
next = NULL;
max_confidence = -1;
- for (i = 0 ; i < node->count ; i++) {+ for (i = 0 ; i < n ; i++) {if (node->children[i].ignored) continue;
if (node->children[i].count == -1) continue;
confidence = moonfish_confidence(node->children + i);
@@ -323,28 +341,50 @@
}
}
-static moonfish_result_t moonfish_start(void *data0)
+static void moonfish_clean(struct moonfish_node *node)
{- struct moonfish_data *data;
+ int i;
+ long int max, visits;
+
+ max = 0;
+
+ for (i = 0 ; i < node->count ; i++) {+ if (node->children[i].ignored) continue;
+ visits = node->children[i].visits;
+ if (visits > max) max = visits;
+ }
+
+ for (i = 0 ; i < node->count ; i++) {+ if (node->children[i].ignored) continue;
+ if (node->children[i].count <= 0) continue;
+ if (node->children[i].visits < max / 4) moonfish_discard(node->children + i);
+ else moonfish_clean(node->children + i);
+ }
+}
+
+static moonfish_result_t moonfish_start(void *data)
+{+ struct moonfish_thread *thread;
int i, count;
- data = data0;
+ thread = data;
- moonfish_search(&data->root->node, &data->root->chess, 0x100);
- while (moonfish_clock() - data->time0 < data->time) {+ moonfish_search(&thread->root->node, &thread->root->chess, 0x100);
+ while (moonfish_clock() - thread->time0 < thread->time) {#ifndef moonfish_mini
- if (data->root->stop) break;
- if (data->root->node.visits + 0x1000 >= data->node_count) {- moonfish_search(&data->root->node, &data->root->chess, data->node_count - data->root->node.visits);
+ if (thread->root->stop) break;
+ if (thread->root->node.visits + 0x1000 >= thread->node_count) {+ moonfish_search(&thread->root->node, &thread->root->chess, thread->node_count - thread->root->node.visits);
break;
}
#endif
- count = data->root->node.count;
- for (i = 0 ; i < data->root->node.count ; i++) {- if (data->root->node.children[i].ignored) count--;
+ count = thread->root->node.count;
+ for (i = 0 ; i < thread->root->node.count ; i++) {+ if (thread->root->node.children[i].ignored) count--;
}
if (count <= 1) break;
- moonfish_search(&data->root->node, &data->root->chess, 0x1000);
+ moonfish_search(&thread->root->node, &thread->root->chess, 0x1000);
+ if (thread->clean) moonfish_clean(&thread->root->node);
}
return moonfish_value;
@@ -352,12 +392,9 @@
void moonfish_best_move(struct moonfish_root *root, struct moonfish_result *result, struct moonfish_options *options)
{- struct moonfish_data data;
+ struct moonfish_thread thread, *threads;
long int time;
int i;
-#ifndef moonfish_no_threads
- thrd_t threads[256];
-#endif
time = LONG_MAX;
if (options->our_time >= 0) time = options->our_time / 16;
@@ -365,20 +402,29 @@
time -= time / 32 + 125;
if (time < 0) time = 0;
- data.root = root;
- data.time = time;
- data.time0 = moonfish_clock();
- if (options->node_count < 0) data.node_count = LONG_MAX;
- else data.node_count = options->node_count;
+ thread.clean = 1;
+ thread.root = root;
+ thread.time = time;
+ thread.time0 = moonfish_clock();
+ if (options->node_count < 0) thread.node_count = LONG_MAX;
+ else thread.node_count = options->node_count;
#ifdef moonfish_no_threads
- moonfish_start(&data);
+ moonfish_start(&thread);
#else
+ threads = malloc(options->thread_count * sizeof *threads);
+ if (threads == NULL) {+ perror("malloc");+ exit(1);
+ }
+
for (i = 0 ; i < options->thread_count ; i++) {- if (thrd_create(threads + i, &moonfish_start, &data) != thrd_success) {+ threads[i] = thread;
+ thread.clean = 0;
+ if (thrd_create(&threads[i].thread, &moonfish_start, threads + i) != thrd_success) {fprintf(stderr, "could not create thread\n");
exit(1);
}
@@ -385,11 +431,13 @@
}
for (i = 0 ; i < options->thread_count ; i++) {- if (thrd_join(threads[i], NULL) != thrd_success) {+ if (thrd_join(threads[i].thread, NULL) != thrd_success) {fprintf(stderr, "could not join thread\n");
exit(1);
}
}
+
+ free(threads);
#endif
--
⑨