Skip to content

Commit 0a065ea

Browse files
implement transposition table multi-threaded initialization. no elo change.
1 parent a74b667 commit 0a065ea

File tree

7 files changed

+86
-44
lines changed

7 files changed

+86
-44
lines changed

src/globals.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,16 @@ typedef unsigned int UINT;
130130
#define POST_XBOARD 2
131131
#define POST_UCI 3
132132

133-
#define MAX_READ 8196
133+
#define MAX_READ 8196
134134

135135
#define MIN_THREADS 1
136-
#define MAX_THREADS 512
136+
#define MAX_THREADS 1024
137137
#define MIN_HASH_SIZE 8
138-
#define MAX_HASH_SIZE 131072
138+
#define MAX_HASH_SIZE 524288
139+
140+
// Parameters
141+
EXTERN S32 gThreads;
142+
EXTERN S32 gHashSize;
139143

140144
// Piece index
141145
#define PAWN 0
@@ -265,7 +269,6 @@ typedef struct s_pv_line {
265269
int size[MAX_PLY];
266270
} PV_LINE;
267271

268-
269272
// Piece Values
270273
#define VALUE_PAWN 180
271274
#define VALUE_KNIGHT 640
@@ -530,7 +533,7 @@ int is_counter_move(MOVE_ORDER *move_order, int prev_color, MOVE previous_mo
530533

531534
// Search
532535
void prepare_search(GAME *game, SETTINGS *settings);
533-
void threads_init(int threads_count);
536+
void threads_init(void);
534537
void search_run(GAME *game, SETTINGS *settings);
535538
U64 get_additional_threads_nodes(void);
536539
U64 get_additional_threads_tbhits(void);
@@ -555,7 +558,7 @@ int piece_value_see(int piece);
555558

556559
// transposition table
557560
void tt_age(void);
558-
void tt_init(size_t size_mb);
561+
void tt_init(void);
559562
void tt_clear(void);
560563
void tt_save(U64 key, TT_RECORD *record);
561564
void tt_read(U64 key, TT_RECORD *record);
@@ -564,7 +567,7 @@ void tt_read(U64 key, TT_RECORD *record);
564567
void analyze_mode(GAME *game);
565568

566569
// Evaluation
567-
int evaluate(GAME *game);
570+
int evaluate(GAME *game);
568571

569572
// Board
570573
void new_game(GAME *game, char *fen);

src/main.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
#define ENGINE "Tucano"
2222
#define AUTHOR "Alcides Schulz"
23-
#define VERSION "12.06"
23+
#define VERSION "12.07"
2424

2525
void develop_workbench(void);
2626
double bench(int depth, int print);
@@ -46,18 +46,18 @@ int main(int argc, char *argv[])
4646
THREAD_ID ponder_thread = 0;
4747

4848
// Options
49-
int threads = 1; // Number of Threads
50-
int hash_size = 64; // Hash Table Size in MB
49+
gThreads = 1;
50+
gHashSize = 64;
5151

5252
printf("%s chess engine by %s - %s (type 'help' for information)\n", ENGINE, AUTHOR, VERSION);
5353

5454
// Command line options
5555
for (int i = 0; i < argc; i++) {
5656
if (!strcmp("-hash", argv[i])) {
57-
if (++i < argc) hash_size = valid_hash_size(atoi(argv[i]));
57+
if (++i < argc) gHashSize = valid_hash_size(atoi(argv[i]));
5858
}
5959
if (!strcmp("-threads", argv[i])) {
60-
if (++i < argc) threads = valid_threads(atoi(argv[i]));
60+
if (++i < argc) gThreads = valid_threads(atoi(argv[i]));
6161
}
6262
if (!strcmp("-ponder", argv[i])) {
6363
ponder_on = TRUE;
@@ -92,16 +92,16 @@ int main(int argc, char *argv[])
9292
}
9393
}
9494

95-
printf(" hash table: %d MB, threads: %d, architecture: %s\n", hash_size, threads, NNUE_ARCH);
95+
printf(" hash table: %d MB, threads: %d, architecture: %s\n", gHashSize, gThreads, NNUE_ARCH);
9696

9797
// Initializations
9898
srand((UINT)19810505);
9999
bb_init();
100100
bb_data_init();
101101
magic_init();
102102
book_init();
103-
tt_init(hash_size);
104-
threads_init(threads);
103+
tt_init();
104+
threads_init();
105105
#ifdef EGTB_SYZYGY
106106
if (strlen(syzygy_path) != 0) {
107107
if (tb_init(syzygy_path)) {
@@ -240,14 +240,14 @@ int main(int argc, char *argv[])
240240
}
241241
if (!strcmp(command, "option")) {
242242
if (strstr(line, "Hash")) {
243-
sscanf(line, "option Hash=%d", &hash_size);
244-
hash_size = valid_hash_size(hash_size);
245-
tt_init(hash_size);
243+
sscanf(line, "option Hash=%d", &gHashSize);
244+
gHashSize = valid_hash_size(gHashSize);
245+
tt_init();
246246
}
247247
if (strstr(line, "Threads")) {
248-
sscanf(line, "option Threads=%d", &threads);
249-
threads = valid_threads(threads);
250-
threads_init(threads);
248+
sscanf(line, "option Threads=%d", &gThreads);
249+
gThreads = valid_threads(gThreads);
250+
threads_init();
251251
}
252252
#ifdef EGTB_SYZYGY
253253
if (strstr(line, "SyzygyPath")) {
@@ -375,21 +375,21 @@ int main(int argc, char *argv[])
375375
}
376376
if (!strcmp(command, "bench")) {
377377
// Benchmark
378-
if (hash_size != 64) {
379-
printf("'bench' command requires hash size of 64. Current hash size is %d. Use 'option Hash=64'.\n", hash_size);
378+
if (gHashSize != 64) {
379+
printf("'bench' command requires hash size of 64. Current hash size is %d. Use 'option Hash=64'.\n", gHashSize);
380380
continue;
381381
}
382-
if (threads != 1) {
383-
printf("'bench' command requires 1 thread only. Current threads is %d. Use 'option Threads=1'.\n", threads);
382+
if (gThreads != 1) {
383+
printf("'bench' command requires 1 thread only. Current threads is %d. Use 'option Threads=1'.\n", gThreads);
384384
continue;
385385
}
386386
bench(16, TRUE);
387387
continue;
388388
}
389389
if (!strcmp(command, "speed")) {
390390
// Measure engine speed
391-
if (hash_size != 64) {
392-
printf("'speed' command requires hash size of 64. Current hash size is %d. Use 'option Hash=64'.\n", hash_size);
391+
if (gHashSize != 64) {
392+
printf("'speed' command requires hash size of 64. Current hash size is %d. Use 'option Hash=64'.\n", gHashSize);
393393
continue;
394394
}
395395
speed_test();

src/nnue_gen.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ void generate_nn_data(int fen_total, int max_depth, int max_nodes, char *output_
7979

8080
FILE *output = fopen(output_filename, "w");
8181

82-
tt_init(TRANS_SIZE_GEN);
82+
gHashSize = TRANS_SIZE_GEN;
83+
tt_init();
8384

8485
UINT start_time = util_get_time();
8586
int fen_count = 0;

src/protocol_uci.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,16 @@ void uci_loop(char *engine_name, char *engine_version, char *engine_author) {
7474
}
7575

7676
if (!strncmp(uci_line, HASH_OPTION_STRING, strlen(HASH_OPTION_STRING))) {
77-
int hash_size = atoi(&uci_line[strlen(HASH_OPTION_STRING)]);
78-
hash_size = valid_hash_size(hash_size);
79-
tt_init(hash_size);
80-
printf("info string Hash set to %d MB\n", hash_size);
77+
gHashSize = valid_hash_size(atoi(&uci_line[strlen(HASH_OPTION_STRING)]));
78+
tt_init();
79+
printf("info string Hash set to %d MB\n", gHashSize);
8180
continue;
8281
}
8382

8483
if (!strncmp(uci_line, THREADS_OPTION_STRING, strlen(THREADS_OPTION_STRING))) {
85-
int threads = atoi(&uci_line[strlen(THREADS_OPTION_STRING)]);
86-
threads = valid_threads(threads);
87-
threads_init(threads);
88-
printf("info string Threads set to %d\n", threads);
84+
gThreads = valid_threads(atoi(&uci_line[strlen(THREADS_OPTION_STRING)]));
85+
threads_init();
86+
printf("info string Threads set to %d\n", gThreads);
8987
continue;
9088
}
9189

src/search_main.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,24 @@ int additional_threads = 0;
3030
//-------------------------------------------------------------------------------------------------
3131
// Create threads data.
3232
//-------------------------------------------------------------------------------------------------
33-
void threads_init(int threads_count)
33+
void threads_init()
3434
{
3535
if (thread_data != NULL) {
3636
ALIGNED_FREE(thread_data);
3737
thread_data = NULL;
3838
}
39-
if (threads_count <= 0) threads_count = 1;
40-
additional_threads = threads_count - 1;
39+
if (gThreads <= 0) gThreads = 1;
40+
additional_threads = gThreads - 1;
4141
if (additional_threads == 0) return;
4242
thread_data = (GAME *)ALIGNED_ALLOC(64, sizeof(GAME) * additional_threads);
4343
if (thread_data == NULL) {
4444
fprintf(stderr, "Error allocating memory for %d additional threads. Running with no paralel search.\n", additional_threads);
4545
additional_threads = 0;
4646
return;
4747
}
48-
memset(thread_data, 0, (size_t)(sizeof(GAME) * additional_threads));
48+
for (int i = 0; i < additional_threads; i++) {
49+
memset(&thread_data[i], 0, sizeof(GAME));
50+
}
4951
}
5052

5153
void *ponder_search(void *game)

src/test_pgn.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ void test_pgn(char *pgn_filename)
3636
int total_positions = 0;
3737
int selected_positions = 0;
3838

39-
tt_init(8);
39+
gHashSize = 8;
40+
tt_init();
4041

4142
while (read_game(pgn_file, pgn_moves, pgn_game, white, black, result)) {
4243
assert(strlen(pgn_moves) < 16384);

src/transposition.c

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,22 @@ struct s_hash_structure {
3434
U8 age;
3535
} hash_table;
3636

37+
typedef struct s_hash_clear {
38+
THREAD_ID thread_id;
39+
void *address;
40+
size_t size;
41+
} HASH_SECTION;
42+
3743
//-------------------------------------------------------------------------------------------------
3844
// Initialization.
3945
//-------------------------------------------------------------------------------------------------
40-
void tt_init(size_t size_mb)
46+
void tt_init()
4147
{
4248
assert(sizeof(TT_ENTRY) == 16);
4349

4450
if (hash_table.address != NULL) free(hash_table.address);
4551

52+
size_t size_mb = gHashSize;
4653
hash_table.size = 2;
4754
while (hash_table.size * 2 <= size_mb) {
4855
hash_table.size *= 2;
@@ -51,7 +58,7 @@ void tt_init(size_t size_mb)
5158

5259
hash_table.address = (TT_ENTRY *)malloc(hash_table.size);
5360
if (!hash_table.address) {
54-
printf("no memory for transposition table!");
61+
fprintf(stderr, "no memory for transposition table, hash=%d !", gHashSize);
5562
exit(-1);
5663
}
5764

@@ -69,12 +76,42 @@ void tt_age(void)
6976
hash_table.age++;
7077
}
7178

79+
//-------------------------------------------------------------------------------------------------
80+
// Clear table section by thread when running multi-thread
81+
//-------------------------------------------------------------------------------------------------
82+
void *tt_clear_section(void *data)
83+
{
84+
HASH_SECTION *section = (HASH_SECTION *)data;
85+
memset(section->address, 0, section->size);
86+
return NULL;
87+
}
88+
7289
//-------------------------------------------------------------------------------------------------
7390
// Clear.
7491
//-------------------------------------------------------------------------------------------------
7592
void tt_clear(void)
7693
{
77-
memset(hash_table.address, 0, hash_table.size);
94+
HASH_SECTION *sections = (HASH_SECTION *)malloc(sizeof(HASH_SECTION) * gThreads);
95+
if (sections == NULL) {
96+
fprintf(stderr, "cannot allocate memory for tt_clear().sections: gHashSize: %d, gThreads=%d\n", gHashSize, gThreads);
97+
exit(-1);
98+
}
99+
size_t section_size = hash_table.size / gThreads;
100+
size_t section_entries = section_size / sizeof(TT_ENTRY);
101+
sections[0].address = hash_table.address;
102+
sections[0].size = section_size;
103+
tt_clear_section(&sections[0]);
104+
if (gThreads > 1) {
105+
for (int i = 1; i < gThreads; i++) {
106+
sections[i].address = hash_table.address + i * section_entries;
107+
sections[i].size = section_size;
108+
THREAD_CREATE(sections[i].thread_id, tt_clear_section, &sections[i]);
109+
}
110+
for (int i = 1; i < gThreads; i++) {
111+
THREAD_WAIT(sections[i].thread_id);
112+
}
113+
}
114+
free(sections);
78115
hash_table.age = 0;
79116
}
80117

0 commit comments

Comments
 (0)