h48

A prototype for an optimal Rubik's cube solver, work in progress.
git clone https://git.tronto.net/h48
Download | Log | Files | Refs | README | LICENSE

commit d1bb88ff0b02f4e314ccecd851162ae30059ce29
parent f91e5c4c83a071ab720417d490fd44a8f4678bc1
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Thu, 17 Apr 2025 17:52:22 +0200

Sped up checkdata for H48 tables

Diffstat:
Msrc/nissy.c | 2+-
Msrc/solvers/h48/gendata_h48.h | 58+++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/solvers/h48/gendata_types_macros.h | 8++++++++
3 files changed, 58 insertions(+), 10 deletions(-)

diff --git a/src/nissy.c b/src/nissy.c @@ -105,7 +105,7 @@ distribution_equal( int wrong; uint8_t i; - for (i = 0, wrong = 0; i <= MAX(maxvalue, 20); i++) { + for (i = 0, wrong = 0; i <= MIN(maxvalue, 20); i++) { if (expected[i] != actual[i]) { wrong++; LOG("Value %" PRIu8 ": expected %" PRIu64 ", found %" diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h @@ -3,8 +3,8 @@ STATIC int64_t gendata_h48(gendata_h48_arg_t [static 1]); STATIC void gendata_h48h0k4(gendata_h48_arg_t [static 1]); STATIC void gendata_h48k2(gendata_h48_arg_t [static 1]); -STATIC void * gendata_h48h0k4_runthread(void *); -STATIC void * gendata_h48k2_runthread(void *); +STATIC void *gendata_h48h0k4_runthread(void *); +STATIC void *gendata_h48k2_runthread(void *); STATIC_INLINE void gendata_h48_mark_atomic(gendata_h48_mark_t [static 1]); STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t [static 1]); @@ -12,6 +12,7 @@ STATIC_INLINE bool gendata_h48k2_dfs_stop( cube_t, int8_t, h48k2_dfs_arg_t [static 1]); STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t [static 1]); STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t [static 1]); +STATIC void *getdistribution_h48_runthread(void *); STATIC void getdistribution_h48(const uint8_t *, uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t); @@ -643,6 +644,26 @@ makeinfo_h48k2(gendata_h48_arg_t arg[static 1]) return info; } +STATIC void * +getdistribution_h48_runthread(void *arg) +{ + getdistribution_h48_data_t *data = (getdistribution_h48_data_t *)arg; + const uint8_t *table; + uint8_t j, k, m; + int64_t i; + + memset(data->distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); + + k = data->k; + table = data->table; + m = H48_MASK(0, k); + for (i = data->min; i < data->max; i++) + for (j = 0; j < H48_DIV(k); j++) + data->distr[(table[i] & (m << (j*k))) >> (j*k)]++; + + return NULL; +} + STATIC void getdistribution_h48( const uint8_t *table, @@ -650,16 +671,35 @@ getdistribution_h48( uint8_t h, uint8_t k ) { - uint8_t val; - int64_t i, h48max; + getdistribution_h48_data_t targ[THREADS]; + pthread_t thread[THREADS]; + uint64_t local_distr[THREADS][INFO_DISTRIBUTION_LEN]; + int64_t i, j, nbytes, sz; + + nbytes = H48_COORDMAX(h) / H48_DIV(k); + sz = nbytes / THREADS; + for (i = 0; i < THREADS; i++) { + targ[i] = (getdistribution_h48_data_t) { + .min = i * sz, + .max = i == THREADS - 1 ? nbytes : (i+1) * sz, + .k = k, + .distr = local_distr[i], + .table = table, + }; + pthread_create(&thread[i], NULL, + getdistribution_h48_runthread, &targ[i]); + } + + for (i = 0; i < THREADS; i++) + pthread_join(thread[i], NULL); memset(distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); + for (i = 0; i < THREADS; i++) + for (j = 0; j < INFO_DISTRIBUTION_LEN; j++) + distr[j] += local_distr[i][j]; - h48max = H48_COORDMAX(h); - for (i = 0; i < h48max; i++) { - val = get_h48_pval(table, i, k); - distr[val]++; - } + for (i = nbytes * H48_DIV(k); i < H48_COORDMAX(h); i++) + distr[get_h48_pval(table, i, k)]++; } STATIC const uint32_t * diff --git a/src/solvers/h48/gendata_types_macros.h b/src/solvers/h48/gendata_types_macros.h @@ -121,3 +121,11 @@ typedef struct { _Atomic uint8_t *table_atomic; pthread_mutex_t **table_mutex; } gendata_h48_mark_t; + +typedef struct { + int64_t min; + int64_t max; + uint8_t k; + uint64_t *distr; + const uint8_t *table; +} getdistribution_h48_data_t;