diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2024-09-17 21:53:36 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2024-09-17 21:53:36 +0200 |
| commit | 10e3c671ac33983b815e90e641633409280f045e (patch) | |
| tree | 17bae570c8d30906d28671f4e9a7af22c4e52085 /src/solvers | |
| parent | ca68b59475f6b1773fa62e6dbc4b68349602b441 (diff) | |
| download | nissy-core-10e3c671ac33983b815e90e641633409280f045e.tar.gz nissy-core-10e3c671ac33983b815e90e641633409280f045e.zip | |
Parallelized h48k2 gendata
Diffstat (limited to 'src/solvers')
| -rw-r--r-- | src/solvers/h48/gendata_h48.h | 92 | ||||
| -rw-r--r-- | src/solvers/h48/map.h | 4 |
2 files changed, 68 insertions, 28 deletions
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h index 135d9d2..480e4f9 100644 --- a/src/solvers/h48/gendata_h48.h +++ b/src/solvers/h48/gendata_h48.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #define H48_MASK(i, k) ((UINT8_BIT(k) - UINT8_C(1)) << H48_SHIFT(i, k)) | 9 | #define H48_MASK(i, k) ((UINT8_BIT(k) - UINT8_C(1)) << H48_SHIFT(i, k)) |
| 10 | 10 | ||
| 11 | #define MAXLEN 20 | 11 | #define MAXLEN 20 |
| 12 | #define CHUNKS COCSEP_CLASSES /* Must be a divisor of H48_COORDMAX_NOEO */ | ||
| 12 | 13 | ||
| 13 | /* | 14 | /* |
| 14 | TODO: This loop over similar h48 coordinates can be improved by only | 15 | TODO: This loop over similar h48 coordinates can be improved by only |
| @@ -69,6 +70,10 @@ typedef struct { | |||
| 69 | uint64_t *selfsim; | 70 | uint64_t *selfsim; |
| 70 | cube_t *crep; | 71 | cube_t *crep; |
| 71 | h48map_t *shortcubes; | 72 | h48map_t *shortcubes; |
| 73 | pthread_mutex_t *shortcubes_mutex; | ||
| 74 | pthread_mutex_t *table_mutex[CHUNKS]; | ||
| 75 | uint64_t *next; | ||
| 76 | uint64_t *count; | ||
| 72 | } h48k2_dfs_arg_t; | 77 | } h48k2_dfs_arg_t; |
| 73 | 78 | ||
| 74 | STATIC uint64_t gen_h48short(gendata_h48short_arg_t *); | 79 | STATIC uint64_t gen_h48short(gendata_h48short_arg_t *); |
| @@ -78,6 +83,7 @@ STATIC int64_t gendata_h48h0k4_bfs(h48h0k4_bfs_arg_t *); | |||
| 78 | STATIC int64_t gendata_h48h0k4_bfs_fromdone(h48h0k4_bfs_arg_t *); | 83 | STATIC int64_t gendata_h48h0k4_bfs_fromdone(h48h0k4_bfs_arg_t *); |
| 79 | STATIC int64_t gendata_h48h0k4_bfs_fromnew(h48h0k4_bfs_arg_t *); | 84 | STATIC int64_t gendata_h48h0k4_bfs_fromnew(h48h0k4_bfs_arg_t *); |
| 80 | STATIC size_t gendata_h48k2(gendata_h48_arg_t *); | 85 | STATIC size_t gendata_h48k2(gendata_h48_arg_t *); |
| 86 | STATIC void * gendata_h48k2_runthread(void *); | ||
| 81 | STATIC_INLINE void gendata_h48k2_mark(cube_t, int8_t, h48k2_dfs_arg_t *); | 87 | STATIC_INLINE void gendata_h48k2_mark(cube_t, int8_t, h48k2_dfs_arg_t *); |
| 82 | STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, uint8_t, h48k2_dfs_arg_t *); | 88 | STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, uint8_t, h48k2_dfs_arg_t *); |
| 83 | STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); | 89 | STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); |
| @@ -339,11 +345,12 @@ gendata_h48k2(gendata_h48_arg_t *arg) | |||
| 339 | 345 | ||
| 340 | uint8_t t, selectedbase, *table; | 346 | uint8_t t, selectedbase, *table; |
| 341 | int64_t j; | 347 | int64_t j; |
| 342 | uint64_t nshort, i, ii; | 348 | uint64_t nshort, i, ii, inext, count; |
| 343 | h48map_t shortcubes; | 349 | h48map_t shortcubes; |
| 344 | kvpair_t kv; | ||
| 345 | gendata_h48short_arg_t shortarg; | 350 | gendata_h48short_arg_t shortarg; |
| 346 | h48k2_dfs_arg_t dfsarg; | 351 | h48k2_dfs_arg_t dfsarg[THREADS]; |
| 352 | pthread_t thread[THREADS]; | ||
| 353 | pthread_mutex_t shortcubes_mutex, table_mutex[CHUNKS]; | ||
| 347 | 354 | ||
| 348 | if (arg->buf == NULL) | 355 | if (arg->buf == NULL) |
| 349 | goto gendata_h48k2_return_size; | 356 | goto gendata_h48k2_return_size; |
| @@ -383,32 +390,37 @@ gendata_h48k2(gendata_h48_arg_t *arg) | |||
| 383 | if (arg->h >= 10) | 390 | if (arg->h >= 10) |
| 384 | arg->info.solver[14] = (arg->h / 10) + '0'; | 391 | arg->info.solver[14] = (arg->h / 10) + '0'; |
| 385 | 392 | ||
| 386 | dfsarg = (h48k2_dfs_arg_t){ | 393 | inext = count = 0; |
| 387 | .h = arg->h, | 394 | pthread_mutex_init(&shortcubes_mutex, NULL); |
| 388 | .k = arg->k, | 395 | for (i = 0; i < CHUNKS; i++) |
| 389 | .base = selectedbase, | 396 | pthread_mutex_init(&table_mutex[i], NULL); |
| 390 | .shortdepth = shortdepth, | 397 | for (i = 0; i < THREADS; i++) { |
| 391 | .cocsepdata = arg->cocsepdata, | 398 | dfsarg[i] = (h48k2_dfs_arg_t){ |
| 392 | .table = table, | 399 | .h = arg->h, |
| 393 | .selfsim = arg->selfsim, | 400 | .k = arg->k, |
| 394 | .crep = arg->crep, | 401 | .base = selectedbase, |
| 395 | .shortcubes = &shortcubes | 402 | .shortdepth = shortdepth, |
| 396 | }; | 403 | .cocsepdata = arg->cocsepdata, |
| 404 | .table = table, | ||
| 405 | .selfsim = arg->selfsim, | ||
| 406 | .crep = arg->crep, | ||
| 407 | .shortcubes = &shortcubes, | ||
| 408 | .shortcubes_mutex = &shortcubes_mutex, | ||
| 409 | .next = &inext, | ||
| 410 | .count = &count, | ||
| 411 | }; | ||
| 412 | for (ii = 0; ii < CHUNKS; ii++) | ||
| 413 | dfsarg[i].table_mutex[ii] = &table_mutex[ii]; | ||
| 397 | 414 | ||
| 398 | i = ii = 0; | 415 | pthread_create( |
| 399 | for (kv = h48map_nextkvpair(&shortcubes, &i); | 416 | &thread[i], NULL, gendata_h48k2_runthread, &dfsarg[i]); |
| 400 | i != shortcubes.capacity; | ||
| 401 | kv = h48map_nextkvpair(&shortcubes, &i) | ||
| 402 | ) { | ||
| 403 | dfsarg.cube = invcoord_h48(kv.key, arg->crep, 11); | ||
| 404 | gendata_h48k2_dfs(&dfsarg); | ||
| 405 | if (++ii % UINT64_C(1000000) == 0) | ||
| 406 | LOG("Processed %" PRIu64 " short cubes\n", ii); | ||
| 407 | } | 417 | } |
| 408 | 418 | ||
| 419 | for (i = 0; i < THREADS; i++) | ||
| 420 | pthread_join(thread[i], NULL); | ||
| 421 | |||
| 409 | h48map_destroy(&shortcubes); | 422 | h48map_destroy(&shortcubes); |
| 410 | 423 | ||
| 411 | arg->info.base = selectedbase; | ||
| 412 | for (j = 0; j < H48_COORDMAX(arg->h); j++) { | 424 | for (j = 0; j < H48_COORDMAX(arg->h); j++) { |
| 413 | t = get_h48_pval(table, j, 2); | 425 | t = get_h48_pval(table, j, 2); |
| 414 | arg->info.distribution[t]++; | 426 | arg->info.distribution[t]++; |
| @@ -420,6 +432,36 @@ gendata_h48k2_return_size: | |||
| 420 | return H48_TABLESIZE(arg->h, 2) + INFOSIZE; | 432 | return H48_TABLESIZE(arg->h, 2) + INFOSIZE; |
| 421 | } | 433 | } |
| 422 | 434 | ||
| 435 | STATIC void * | ||
| 436 | gendata_h48k2_runthread(void *arg) | ||
| 437 | { | ||
| 438 | kvpair_t kv; | ||
| 439 | h48k2_dfs_arg_t *dfsarg; | ||
| 440 | |||
| 441 | dfsarg = (h48k2_dfs_arg_t *)arg; | ||
| 442 | |||
| 443 | while (true) { | ||
| 444 | pthread_mutex_lock(dfsarg->shortcubes_mutex); | ||
| 445 | |||
| 446 | kv = h48map_nextkvpair(dfsarg->shortcubes, dfsarg->next); | ||
| 447 | if (*dfsarg->next == dfsarg->shortcubes->capacity) { | ||
| 448 | pthread_mutex_unlock(dfsarg->shortcubes_mutex); | ||
| 449 | break; | ||
| 450 | } | ||
| 451 | dfsarg->cube = invcoord_h48(kv.key, dfsarg->crep, 11); | ||
| 452 | (*dfsarg->count)++; | ||
| 453 | if (*dfsarg->count % UINT64_C(1000000) == 0) | ||
| 454 | LOG("Processing %" PRIu64 "th short cube\n", | ||
| 455 | *dfsarg->count); | ||
| 456 | |||
| 457 | pthread_mutex_unlock(dfsarg->shortcubes_mutex); | ||
| 458 | |||
| 459 | gendata_h48k2_dfs(dfsarg); | ||
| 460 | } | ||
| 461 | |||
| 462 | return NULL; | ||
| 463 | } | ||
| 464 | |||
| 423 | STATIC void | 465 | STATIC void |
| 424 | gendata_h48k2_dfs(h48k2_dfs_arg_t *arg) | 466 | gendata_h48k2_dfs(h48k2_dfs_arg_t *arg) |
| 425 | { | 467 | { |
| @@ -488,9 +530,11 @@ gendata_h48k2_mark(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg) | |||
| 488 | FOREACH_H48SIM(cube, arg->cocsepdata, arg->selfsim, | 530 | FOREACH_H48SIM(cube, arg->cocsepdata, arg->selfsim, |
| 489 | fullcoord = coord_h48(cube, arg->cocsepdata, 11); | 531 | fullcoord = coord_h48(cube, arg->cocsepdata, 11); |
| 490 | coord = fullcoord >> (int64_t)(11 - arg->h); | 532 | coord = fullcoord >> (int64_t)(11 - arg->h); |
| 533 | pthread_mutex_lock(arg->table_mutex[coord % CHUNKS]); | ||
| 491 | oldval = get_h48_pval(arg->table, coord, arg->k); | 534 | oldval = get_h48_pval(arg->table, coord, arg->k); |
| 492 | newval = (uint8_t)MAX(depth, 0); | 535 | newval = (uint8_t)MAX(depth, 0); |
| 493 | set_h48_pval(arg->table, coord, arg->k, MIN(oldval, newval)); | 536 | set_h48_pval(arg->table, coord, arg->k, MIN(oldval, newval)); |
| 537 | pthread_mutex_unlock(arg->table_mutex[coord % CHUNKS]); | ||
| 494 | ) | 538 | ) |
| 495 | } | 539 | } |
| 496 | 540 | ||
diff --git a/src/solvers/h48/map.h b/src/solvers/h48/map.h index baffe39..e74a5dd 100644 --- a/src/solvers/h48/map.h +++ b/src/solvers/h48/map.h | |||
| @@ -88,10 +88,6 @@ h48map_nextkvpair(h48map_t *map, uint64_t *p) | |||
| 88 | kv.key = MAP_KEYMASK; | 88 | kv.key = MAP_KEYMASK; |
| 89 | kv.val = MAP_UNSET_VAL; | 89 | kv.val = MAP_UNSET_VAL; |
| 90 | 90 | ||
| 91 | DBG_ASSERT(*p < map->capacity, kv, | ||
| 92 | "Error looping over map: given index %" PRIu64 " is out of " | ||
| 93 | "range [0,%" PRIu64 "]", *p, map->capacity); | ||
| 94 | |||
| 95 | for ( ; *p < map->capacity; (*p)++) { | 91 | for ( ; *p < map->capacity; (*p)++) { |
| 96 | if (map->table[*p] != MAP_UNSET) { | 92 | if (map->table[*p] != MAP_UNSET) { |
| 97 | pair = map->table[(*p)++]; | 93 | pair = map->table[(*p)++]; |
