diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-06-18 09:22:25 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-06-18 09:22:29 +0200 |
| commit | 5a8ca71aa8255fb76335bf41c8168cfe45eb9574 (patch) | |
| tree | 16600832fe700bf4475bc33bb9e348a3d8b0fbed /src | |
| parent | 97c117d015a868d281c78807884f7ff570171a68 (diff) | |
| download | nissy-core-5a8ca71aa8255fb76335bf41c8168cfe45eb9574.tar.gz nissy-core-5a8ca71aa8255fb76335bf41c8168cfe45eb9574.zip | |
Big speedup for H48 solver (heuristic sort of tasks)
Diffstat (limited to '')
| -rw-r--r-- | src/solvers/h48/solve.h | 65 |
1 files changed, 46 insertions, 19 deletions
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index 348c122..7ba70c6 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -1,9 +1,18 @@ | |||
| 1 | #define STARTING_MOVES 3 | 1 | #define H48_STARTING_MOVES 4 |
| 2 | #define STARTING_CUBES 3240 /* Number of 3-move sequences */ | 2 | |
| 3 | #if H48_STARTING_MOVES == 3 | ||
| 4 | #define H48_STARTING_CUBES 3240 /* Number of 3-move sequences */ | ||
| 5 | #elif H48_STARTING_MOVES == 4 | ||
| 6 | #define H48_STARTING_CUBES 43254 /* Number of 4-move sequences */ | ||
| 7 | #endif | ||
| 8 | |||
| 9 | #define H48_SORT_TASKS_MIN_DEPTH 17 | ||
| 10 | #define H48_LOG_PROGRESS_MIN_DEPTH 15 | ||
| 3 | 11 | ||
| 4 | typedef struct { | 12 | typedef struct { |
| 5 | cube_t cube; | 13 | cube_t cube; |
| 6 | uint8_t moves[STARTING_MOVES]; | 14 | uint8_t moves[H48_STARTING_MOVES]; |
| 15 | int64_t nodes_visited; | ||
| 7 | } solve_h48_task_t; | 16 | } solve_h48_task_t; |
| 8 | 17 | ||
| 9 | typedef struct { | 18 | typedef struct { |
| @@ -42,7 +51,7 @@ typedef struct { | |||
| 42 | typedef struct { | 51 | typedef struct { |
| 43 | cube_t cube; | 52 | cube_t cube; |
| 44 | int8_t nmoves; | 53 | int8_t nmoves; |
| 45 | uint8_t moves[STARTING_MOVES]; | 54 | uint8_t moves[H48_STARTING_MOVES]; |
| 46 | int8_t minmoves; | 55 | int8_t minmoves; |
| 47 | int8_t maxmoves; | 56 | int8_t maxmoves; |
| 48 | int8_t *shortest_sol; | 57 | int8_t *shortest_sol; |
| @@ -55,10 +64,11 @@ STATIC long long solve_h48_dispatch(oriented_cube_t, const char *, unsigned, | |||
| 55 | STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t [static 1]); | 64 | STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t [static 1]); |
| 56 | STATIC int64_t solve_h48_maketasks( | 65 | STATIC int64_t solve_h48_maketasks( |
| 57 | dfsarg_solve_h48_t [static 1], dfsarg_solve_h48_maketasks_t [static 1], | 66 | dfsarg_solve_h48_t [static 1], dfsarg_solve_h48_maketasks_t [static 1], |
| 58 | solve_h48_task_t [static STARTING_CUBES], int [static 1]); | 67 | solve_h48_task_t [static H48_STARTING_CUBES], int [static 1]); |
| 59 | STATIC void *solve_h48_runthread(void *); | 68 | STATIC void *solve_h48_runthread(void *); |
| 60 | STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]); | 69 | STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]); |
| 61 | STATIC void solve_h48_log_solutions(solution_list_t [static 1], size_t); | 70 | STATIC void solve_h48_log_solutions(solution_list_t [static 1], size_t); |
| 71 | STATIC int solve_h48_compare_tasks(const void *, const void *); | ||
| 62 | STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t, | 72 | STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t, |
| 63 | uint8_t, uint64_t, const unsigned char *, size_t, char *, | 73 | uint8_t, uint64_t, const unsigned char *, size_t, char *, |
| 64 | long long [static NISSY_SIZE_SOLVE_STATS], int (*)(void *), void *); | 74 | long long [static NISSY_SIZE_SOLVE_STATS], int (*)(void *), void *); |
| @@ -273,27 +283,29 @@ STATIC void * | |||
| 273 | solve_h48_runthread(void *arg) | 283 | solve_h48_runthread(void *arg) |
| 274 | { | 284 | { |
| 275 | int i, j; | 285 | int i, j; |
| 276 | solve_h48_task_t task; | 286 | int64_t nprev; |
| 277 | dfsarg_solve_h48_t *dfsarg; | 287 | dfsarg_solve_h48_t *dfsarg; |
| 278 | 288 | ||
| 279 | dfsarg = (dfsarg_solve_h48_t *)arg; | 289 | dfsarg = (dfsarg_solve_h48_t *)arg; |
| 280 | 290 | ||
| 291 | nprev = 0; | ||
| 281 | for (i = dfsarg->thread_id; i < dfsarg->ntasks; i += dfsarg->threads) { | 292 | for (i = dfsarg->thread_id; i < dfsarg->ntasks; i += dfsarg->threads) { |
| 282 | if (*dfsarg->status == NISSY_STATUS_STOP) | 293 | if (*dfsarg->status == NISSY_STATUS_STOP) |
| 283 | goto solve_h48_runthread_end; | 294 | goto solve_h48_runthread_end; |
| 284 | while (*dfsarg->status == NISSY_STATUS_PAUSE) | 295 | while (*dfsarg->status == NISSY_STATUS_PAUSE) |
| 285 | msleep(BASE_SLEEP_TIME); | 296 | msleep(BASE_SLEEP_TIME); |
| 286 | 297 | ||
| 287 | task = dfsarg->tasks[i]; | 298 | dfsarg->tasks[i].nodes_visited = 0; |
| 288 | 299 | ||
| 289 | solution_moves_reset(dfsarg->solution_moves); | 300 | solution_moves_reset(dfsarg->solution_moves); |
| 290 | memcpy( | 301 | memcpy(dfsarg->solution_moves->moves, |
| 291 | dfsarg->solution_moves->moves, task.moves, STARTING_MOVES); | 302 | dfsarg->tasks[i].moves, H48_STARTING_MOVES); |
| 292 | dfsarg->solution_moves->nmoves = STARTING_MOVES; | 303 | dfsarg->solution_moves->nmoves = H48_STARTING_MOVES; |
| 293 | 304 | ||
| 294 | dfsarg->cube = dfsarg->start_cube; | 305 | dfsarg->cube = dfsarg->start_cube; |
| 295 | for (j = 0; j < STARTING_MOVES; j++) | 306 | for (j = 0; j < H48_STARTING_MOVES; j++) |
| 296 | dfsarg->cube = move(dfsarg->cube, task.moves[j]); | 307 | dfsarg->cube = |
| 308 | move(dfsarg->cube, dfsarg->tasks[i].moves[j]); | ||
| 297 | dfsarg->inverse = inverse(dfsarg->cube); | 309 | dfsarg->inverse = inverse(dfsarg->cube); |
| 298 | 310 | ||
| 299 | dfsarg->lb_normal = 0; | 311 | dfsarg->lb_normal = 0; |
| @@ -304,6 +316,9 @@ solve_h48_runthread(void *arg) | |||
| 304 | dfsarg->movemask_inverse = MM18_ALLMOVES; | 316 | dfsarg->movemask_inverse = MM18_ALLMOVES; |
| 305 | 317 | ||
| 306 | solve_h48_dfs(dfsarg); | 318 | solve_h48_dfs(dfsarg); |
| 319 | |||
| 320 | dfsarg->tasks[i].nodes_visited = dfsarg->nodes_visited - nprev; | ||
| 321 | nprev = dfsarg->nodes_visited; | ||
| 307 | } | 322 | } |
| 308 | 323 | ||
| 309 | solve_h48_runthread_end: | 324 | solve_h48_runthread_end: |
| @@ -315,7 +330,7 @@ STATIC int64_t | |||
| 315 | solve_h48_maketasks( | 330 | solve_h48_maketasks( |
| 316 | dfsarg_solve_h48_t solve_arg[static 1], | 331 | dfsarg_solve_h48_t solve_arg[static 1], |
| 317 | dfsarg_solve_h48_maketasks_t maketasks_arg[static 1], | 332 | dfsarg_solve_h48_maketasks_t maketasks_arg[static 1], |
| 318 | solve_h48_task_t tasks[static STARTING_CUBES], | 333 | solve_h48_task_t tasks[static H48_STARTING_CUBES], |
| 319 | int ntasks[static 1] | 334 | int ntasks[static 1] |
| 320 | ) | 335 | ) |
| 321 | { | 336 | { |
| @@ -343,10 +358,10 @@ solve_h48_maketasks( | |||
| 343 | return appret < 0 ? appret : NISSY_OK; | 358 | return appret < 0 ? appret : NISSY_OK; |
| 344 | } | 359 | } |
| 345 | 360 | ||
| 346 | if (maketasks_arg->nmoves == STARTING_MOVES) { | 361 | if (maketasks_arg->nmoves == H48_STARTING_MOVES) { |
| 347 | tasks[*ntasks].cube = maketasks_arg->cube; | 362 | tasks[*ntasks].cube = maketasks_arg->cube; |
| 348 | memcpy(tasks[*ntasks].moves, | 363 | memcpy(tasks[*ntasks].moves, |
| 349 | maketasks_arg->moves, STARTING_MOVES); | 364 | maketasks_arg->moves, H48_STARTING_MOVES); |
| 350 | (*ntasks)++; | 365 | (*ntasks)++; |
| 351 | return NISSY_OK; | 366 | return NISSY_OK; |
| 352 | } | 367 | } |
| @@ -399,6 +414,13 @@ solve_h48_log_solutions(solution_list_t s[static 1], size_t e) | |||
| 399 | } | 414 | } |
| 400 | } | 415 | } |
| 401 | 416 | ||
| 417 | STATIC int | ||
| 418 | solve_h48_compare_tasks(const void *x, const void *y) | ||
| 419 | { | ||
| 420 | return ((solve_h48_task_t *)y)->nodes_visited | ||
| 421 | - ((solve_h48_task_t *)x)->nodes_visited; | ||
| 422 | } | ||
| 423 | |||
| 402 | STATIC int64_t | 424 | STATIC int64_t |
| 403 | solve_h48( | 425 | solve_h48( |
| 404 | oriented_cube_t oc, | 426 | oriented_cube_t oc, |
| @@ -422,7 +444,7 @@ solve_h48( | |||
| 422 | size_t lastused; | 444 | size_t lastused; |
| 423 | int8_t d; | 445 | int8_t d; |
| 424 | dfsarg_solve_h48_t arg[THREADS]; | 446 | dfsarg_solve_h48_t arg[THREADS]; |
| 425 | solve_h48_task_t tasks[STARTING_CUBES]; | 447 | solve_h48_task_t tasks[H48_STARTING_CUBES]; |
| 426 | dfsarg_solve_h48_maketasks_t maketasks_arg; | 448 | dfsarg_solve_h48_maketasks_t maketasks_arg; |
| 427 | long double fallback_rate, lookups_per_node; | 449 | long double fallback_rate, lookups_per_node; |
| 428 | uint64_t offset; | 450 | uint64_t offset; |
| @@ -516,7 +538,8 @@ solve_h48( | |||
| 516 | solve_h48_maketasks(&arg[0], &maketasks_arg, tasks, &ntasks); | 538 | solve_h48_maketasks(&arg[0], &maketasks_arg, tasks, &ntasks); |
| 517 | if (ntasks < 0) | 539 | if (ntasks < 0) |
| 518 | goto solve_h48_error_solutions_buffer; | 540 | goto solve_h48_error_solutions_buffer; |
| 519 | if (solutions_done(&sollist, &settings, MAX(minmoves, STARTING_MOVES))) | 541 | if (solutions_done(&sollist, &settings, |
| 542 | MAX(minmoves, H48_STARTING_MOVES))) | ||
| 520 | goto solve_h48_done; | 543 | goto solve_h48_done; |
| 521 | 544 | ||
| 522 | for (i = 0; i < threads; i++) { | 545 | for (i = 0; i < threads; i++) { |
| @@ -535,17 +558,21 @@ solve_h48( | |||
| 535 | "be available on this system (can't sleep()).\n"); | 558 | "be available on this system (can't sleep()).\n"); |
| 536 | } | 559 | } |
| 537 | for ( | 560 | for ( |
| 538 | d = MAX(minmoves, STARTING_MOVES + 1); | 561 | d = MAX(minmoves, H48_STARTING_MOVES + 1); |
| 539 | !(solutions_done(&sollist, &settings, d)) && | 562 | !(solutions_done(&sollist, &settings, d)) && |
| 540 | status != NISSY_STATUS_STOP; | 563 | status != NISSY_STATUS_STOP; |
| 541 | d++ | 564 | d++ |
| 542 | ) { | 565 | ) { |
| 543 | if (d >= 15) { | 566 | if (d >= H48_LOG_PROGRESS_MIN_DEPTH) { |
| 544 | LOG("[H48 solve] Found %" PRId64 " solutions, " | 567 | LOG("[H48 solve] Found %" PRId64 " solutions, " |
| 545 | "searching at depth %" PRId8 "\n", | 568 | "searching at depth %" PRId8 "\n", |
| 546 | sollist.nsols, d); | 569 | sollist.nsols, d); |
| 547 | } | 570 | } |
| 548 | 571 | ||
| 572 | if (d >= H48_SORT_TASKS_MIN_DEPTH) | ||
| 573 | qsort(tasks, ntasks, sizeof(solve_h48_task_t), | ||
| 574 | solve_h48_compare_tasks); | ||
| 575 | |||
| 549 | for (i = 0; i < threads; i++) { | 576 | for (i = 0; i < threads; i++) { |
| 550 | arg[i].target_depth = d; | 577 | arg[i].target_depth = d; |
| 551 | arg[i].thread_done = false; | 578 | arg[i].thread_done = false; |
