From 6f465d10588d756aef6a09474b329df7088197ea Mon Sep 17 00:00:00 2001 From: Jean-loup Gailly Date: Mon, 1 Feb 2010 19:13:42 +0100 Subject: [PATCH] Do not use all memory during pondering. --- uct/internal.h | 3 ++- uct/uct.c | 6 ++++-- uct/walk.c | 9 ++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/uct/internal.h b/uct/internal.h index 0e9912e..74d9979 100644 --- a/uct/internal.h +++ b/uct/internal.h @@ -41,7 +41,8 @@ struct uct { } thread_model; bool parallel_tree; bool virtual_loss; - bool pondering; + bool pondering_opt; /* User wants pondering */ + bool pondering; /* Actually pondering now */ int fuseki_end; int yose_start; diff --git a/uct/uct.c b/uct/uct.c index ec2e26f..278a976 100644 --- a/uct/uct.c +++ b/uct/uct.c @@ -610,6 +610,7 @@ uct_pondering_start(struct uct *u, struct board *b0, struct tree *t, enum stone { if (UDEBUGL(1)) fprintf(stderr, "Starting to ponder with color %s\n", stone2str(stone_other(color))); + u->pondering = true; /* We need a local board copy to ponder upon. */ struct board *b = malloc(sizeof(*b)); board_copy(b, b0); @@ -627,6 +628,7 @@ uct_pondering_start(struct uct *u, struct board *b0, struct tree *t, enum stone static void uct_pondering_stop(struct uct *u) { + u->pondering = false; if (!thread_manager_running) return; @@ -702,7 +704,7 @@ uct_genmove(struct engine *e, struct board *b, struct time_info *ti, enum stone * Of course this is the case for opponent resign as well. * (ii) More importantly, the ownermap will get skewed since * the UCT will start cutting off any playouts. */ - if (u->pondering && !is_pass(best->coord)) { + if (u->pondering_opt && !is_pass(best->coord)) { uct_pondering_start(u, b, u->t, stone_other(color)); } if (UDEBUGL(2)) { @@ -885,7 +887,7 @@ uct_state_init(char *arg, struct board *b) } } else if (!strcasecmp(optname, "pondering")) { /* Keep searching even during opponent's turn. */ - u->pondering = !optval || atoi(optval); + u->pondering_opt = !optval || atoi(optval); } else if (!strcasecmp(optname, "fuseki_end") && optval) { /* At the very beginning it's not worth thinking too long because the * playout evaluations are very noisy. So gradually increase the thinking diff --git a/uct/walk.c b/uct/walk.c index 4972ea9..ad2fb56 100644 --- a/uct/walk.c +++ b/uct/walk.c @@ -19,6 +19,9 @@ #include "uct/uct.h" #include "uct/walk.h" +/*Fill at most 90% of the tree when pondering: */ +#define PONDERING_MAX_MEM_PERCENT 90 + float uct_get_extra_komi(struct uct *u, struct board *b) { @@ -91,6 +94,10 @@ uct_leaf_node(struct uct *u, struct board *b, enum stone player_color, enum stone next_color = stone_other(node_color); int parity = (next_color == player_color ? 1 : -1); + unsigned long max_tree_size = u->max_tree_size; + if (u->pondering) + max_tree_size = (max_tree_size * PONDERING_MAX_MEM_PERCENT) / 100; + /* We need to make sure only one thread expands the node. If * we are unlucky enough for two threads to meet in the same * node, the latter one will simply do another simulation from @@ -98,7 +105,7 @@ uct_leaf_node(struct uct *u, struct board *b, enum stone player_color, * the maximum in multi-threaded case but not by much so it's ok. * The size test must be before the test&set not after, to allow * expansion of the node later if enough nodes have been freed. */ - if (n->u.playouts >= u->expand_p && t->nodes_size < u->max_tree_size + if (n->u.playouts >= u->expand_p && t->nodes_size < max_tree_size && !__sync_lock_test_and_set(&n->is_expanded, 1)) { tree_expand_node(t, n, b, next_color, u, parity); } -- 2.11.4.GIT