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 73e64898e36cb2cdad5ec03ac907ed9e866fd5a2
parent fb9ae9e41eaf01b3651395fdd450ac1a4743e592
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Fri, 10 Nov 2023 16:04:06 +0100

"Fixed" benchmark (actually removed)

Diffstat:
MREADME.md | 8+-------
Mbenchmark/bench.c | 180+++++++++++++++----------------------------------------------------------------
Mbenchmark/bench.sh | 2+-
Abenchmark/cube-bench.c | 147+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 182 insertions(+), 155 deletions(-)

diff --git a/README.md b/README.md @@ -26,10 +26,4 @@ regex, for example: $ TEST=coord make test ``` -You can also run - -``` -$ make benchmark -``` - -for benchmarks. +Due to ongoing changes, benchmarks are currently broken. diff --git a/benchmark/bench.c b/benchmark/bench.c @@ -6,132 +6,16 @@ #include "../cube.h" -#define MOVES 100000000 -#define TRANS 100000000 -#define COMP 100000000 -#define INV 100000000 - -#define GEN_MOVES 10000 -#define GEN_TRANS 10000 -#define GEN_CUBES 10000 - -static move_t gen_moves[GEN_MOVES]; -static trans_t gen_trans[GEN_TRANS]; -static cube_t gen_cubes[GEN_CUBES]; - -void setup_moves(void); -void setup_trans(void); -void setup_cube(void); -void run_moves(void); -void run_trans(void); -void run_comp(void); -void run_inv(void); -double bench(void (*)(void), void (*)(void), char *); - -void -setup_moves(void) -{ - int i; - - for (i = 0; i < GEN_MOVES; i++) - gen_moves[i] = (move_t)rand() % 18; -} - -void -setup_trans(void) -{ - int i; - - for (i = 0; i < GEN_TRANS; i++) - gen_trans[i] = (trans_t)rand() % 48; -} - -void -setup_cubes(void) -{ - int i, j; - move_t m; - - for (i = 0; i < GEN_CUBES; i++) { - gen_cubes[i] = solvedcube(); - for (j = 0; j < 30; j++) { - m = (move_t)rand() % 18; - gen_cubes[i] = move(gen_cubes[i], m); - } - } -} - -void -run_moves(void) -{ - int i; - cube_t c; - char str[1000]; - - c = solvedcube(); - for (i = 0; i < MOVES; i++) - c = move(c, gen_moves[i % GEN_MOVES]); - - writecube(H48, c, str); - str[3] = 0; - printf("> moves: resulting cube, first piece: %s\n", str); - fflush(stdout); -} - -void -run_trans(void) -{ - int i; - cube_t c; - char str[1000]; - - c = solvedcube(); - for (i = 0; i < TRANS; i++) - c = transform(c, gen_trans[i % GEN_TRANS]); - - writecube(H48, c, str); - str[3] = 0; - printf("> trans: resulting cube, first piece: %s\n", str); - fflush(stdout); -} - -void -run_comp(void) -{ - int i; - cube_t c; - char str[1000]; - - c = solvedcube(); - for (i = 0; i < COMP; i++) - c = compose(c, gen_cubes[i % GEN_CUBES]); - - writecube(H48, c, str); - str[3] = 0; - printf("> comp: resulting cube, first piece: %s\n", str); - fflush(stdout); -} - -void -run_inv(void) -{ - int i, j; - char str[1000]; - - for (i = 0; i < COMP; i++) { - j = i % (GEN_CUBES-1); - gen_cubes[j] = inverse(gen_cubes[j+1]); - } - - writecube(H48, gen_cubes[0], str); - str[3] = 0; - printf("> comp: resulting cube, first piece: %s\n", str); - fflush(stdout); -} +#define MOVES 100000000 +#define TRANS 100000000 +#define COMPOSE 100000000 +#define INVERSE 100000000 double -bench(void (*run)(void), void (*setup)(void), char *name) +bench(cube_t (*run)(int64_t), int64_t n, char *name) { + char str[1000]; + cube_t cube; struct timespec start, end; double tdiff, tdsec, tdnano; @@ -144,14 +28,16 @@ bench(void (*run)(void), void (*setup)(void), char *name) return -1.0; } - printf("> %s: setting up benchmark...\n", name); - fflush(stdout); - if (setup != NULL) - setup(); printf("> %s: running benchmark...\n", name); fflush(stdout); clock_gettime(CLOCK_MONOTONIC, &start); - run(); + + cube = run(n); + writecube("H48", cube, str); + str[3] = 0; + printf("> %s: resulting cube, first piece: %s\n", name, str); + fflush(stdout); + clock_gettime(CLOCK_MONOTONIC, &end); tdsec = end.tv_sec - start.tv_sec; tdnano = end.tv_nsec - start.tv_nsec; @@ -163,34 +49,34 @@ bench(void (*run)(void), void (*setup)(void), char *name) } int main() { - double tmoves, ttrans, tcomp, tinv; + double tmoves, ttrans, tcompose, tinverse; printf( - "Benchmarks settings:\n" - "MOVES:\t%d\nTRANS:\t%d\nCOMP:\t%d\nINV:\t%d\n", - MOVES, TRANS, COMP, INV + "Benchmarks settings:\n" + "MOVES:\t%d\nTRANS:\t%d\nCOMPOSE:\t%d\nINVERSE:\t%d\n", + MOVES, TRANS, COMPOSE, INVERSE ); fflush(stdout); srand(time(NULL)); - tmoves = bench(run_moves, setup_moves, "moves"); - ttrans = bench(run_trans, setup_trans, "trans"); - tcomp = bench(run_comp, setup_cubes, "comp"); - tinv = bench(run_inv, setup_cubes, "inv"); + tmoves = bench(run_moves, MOVES, "moves"); + ttrans = bench(run_trans, TRANS, "trans"); + tcompose = bench(run_compose, COMPOSE, "compose"); + tinverse = bench(run_inverse, INVERSE, "inverse"); printf( - "\nBenchmark summary:\n" - "moves: %d moves in %.4fs (%.4f MTPS)\n" - "trans: %d trans in %.4fs (%.4f MTPS)\n" - "comp: %d comps in %.4fs (%.4f MCPS)\n" - "inv: %d invs in %.4fs (%.4f MIPS)\n" - "Total time: %.4f\n", - MOVES, tmoves, MOVES / (1e6 * tmoves), - TRANS, ttrans, TRANS / (1e6 * ttrans), - COMP, tcomp, COMP / (1e6 * tcomp), - INV, tinv, INV / (1e6 * tinv), - tmoves + ttrans + tcomp + tinv + "\nBenchmark summary:\n" + "moves: %d moves in %.4fs (%.4f MTPS)\n" + "trans: %d transformations in %.4fs (%.4f MTPS)\n" + "compose: %d compositions in %.4fs (%.4f MCPS)\n" + "inverse: %d inverses in %.4fs (%.4f MIPS)\n" + "Total time: %.4f\n", + MOVES, tmoves, MOVES / (1e6 * tmoves), + TRANS, ttrans, TRANS / (1e6 * ttrans), + COMPOSE, tcompose, COMPOSE / (1e6 * tcompose), + INVERSE, tinverse, INVERSE / (1e6 * tinverse), + tmoves + ttrans + tcompose + tinverse ); return 0; diff --git a/benchmark/bench.sh b/benchmark/bench.sh @@ -9,7 +9,7 @@ BENCHBIN="benchmark/run" BENCHDIR="benchmark/results" CUBEOBJ="cube.o" -$CC -o $BENCHBIN benchmark/bench.c $CUBEOBJ || exit 1; +$CC -D_POSIX_C_SOURCE=199309L -o $BENCHBIN benchmark/bench.c $CUBEOBJ || exit 1 d="$(date +'%Y-%m-%d-%H-%M-%S')" mkdir -p "$BENCHDIR" diff --git a/benchmark/cube-bench.c b/benchmark/cube-bench.c @@ -0,0 +1,147 @@ +/****************************************************************************** +Section: benchmarks + +Here you can find some simple functions that can be used to benchmark the +rest of the code. +******************************************************************************/ + +#define RANDOMCUBES 157 + +static void +setup_randomcubes(cube_fast_t *cubes) +{ + int i; + + for (i = 0; i < RANDOMCUBES; i++) + cubes[i] = run_moves(i*4); +} + +cube_t +run_moves(int64_t n) +{ + cube_fast_t fast; + int64_t m, i; + + fast = solvedcube(); + m = n / 18; + + for (i = 0; i < m; i++) { + fast = _move_U(fast); + fast = _move_U2(fast); + fast = _move_U3(fast); + fast = _move_D(fast); + fast = _move_D2(fast); + fast = _move_D3(fast); + fast = _move_R(fast); + fast = _move_R2(fast); + fast = _move_R3(fast); + fast = _move_L(fast); + fast = _move_L2(fast); + fast = _move_L3(fast); + fast = _move_F(fast); + fast = _move_F2(fast); + fast = _move_F3(fast); + fast = _move_B(fast); + fast = _move_B2(fast); + fast = _move_B3(fast); + } + + for (i = m * 18; i < n; i++) + fast = _move_F(fast); + + return fast; +} + +cube_t +run_trans(int64_t n) +{ + cube_fast_t fast; + int64_t m, i; + + fast = run_moves(33); + m = n / 18; + + for (i = 0; i < m; i++) { + fast = _trans_UFr(fast); + fast = _trans_ULr(fast); + fast = _trans_UBr(fast); + fast = _trans_URr(fast); + fast = _trans_DFr(fast); + fast = _trans_DLr(fast); + fast = _trans_DBr(fast); + fast = _trans_DRr(fast); + fast = _trans_RUr(fast); + fast = _trans_RFr(fast); + fast = _trans_RDr(fast); + fast = _trans_RBr(fast); + fast = _trans_LUr(fast); + fast = _trans_LFr(fast); + fast = _trans_LDr(fast); + fast = _trans_LBr(fast); + fast = _trans_FUr(fast); + fast = _trans_FRr(fast); + fast = _trans_FDr(fast); + fast = _trans_FLr(fast); + fast = _trans_BUr(fast); + fast = _trans_BRr(fast); + fast = _trans_BDr(fast); + fast = _trans_BLr(fast); + fast = _trans_UFm(fast); + fast = _trans_ULm(fast); + fast = _trans_UBm(fast); + fast = _trans_URm(fast); + fast = _trans_DFm(fast); + fast = _trans_DLm(fast); + fast = _trans_DBm(fast); + fast = _trans_DRm(fast); + fast = _trans_RUm(fast); + fast = _trans_RFm(fast); + fast = _trans_RDm(fast); + fast = _trans_RBm(fast); + fast = _trans_LUm(fast); + fast = _trans_LFm(fast); + fast = _trans_LDm(fast); + fast = _trans_LBm(fast); + fast = _trans_FUm(fast); + fast = _trans_FRm(fast); + fast = _trans_FDm(fast); + fast = _trans_FLm(fast); + fast = _trans_BUm(fast); + fast = _trans_BRm(fast); + fast = _trans_BDm(fast); + fast = _trans_BLm(fast); + } + + for (i = m * 18; i < n; i++) + fast = _trans_FRm(fast); + + return fast; +} + +cube_t +run_compose(int64_t n) +{ + cube_fast_t fast, cubes[RANDOMCUBES]; + int64_t i; + + setup_randomcubes(cubes); + + for (i = 0; i < n; i++) + fast = compose_fast(fast, cubes[i % RANDOMCUBES]); + + return fast; +} + +cube_t +run_inverse(int64_t n) +{ + cube_fast_t fast, cubes[RANDOMCUBES]; + int64_t i; + + setup_randomcubes(cubes); + + for (i = 0; i < n; i++) + fast = inverse_fast(cubes[i % RANDOMCUBES]); + + return fast; +}