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 287f6c4067a206fb1c18eb779ef8463f06c0e5e1
parent b3622e04dfb8317b745f8c911d31dc80bc2f9d66
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Mon, 23 Oct 2023 18:48:35 +0200

Added benchmarking

Diffstat:
MMakefile | 2+-
MREADME.md | 1-
Mbenchmark/bench.c | 188++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mbenchmark/bench.sh | 2++
4 files changed, 190 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile @@ -17,7 +17,7 @@ debugcube.o: ${CC} ${DBGFLAGS} -c -o debugcube.o src/*.c clean: - rm -rf solve + rm -rf *.o test: debugcube.o ./test/test.sh diff --git a/README.md b/README.md @@ -4,7 +4,6 @@ Work in progress. TODO: -* setup benchmarks * AVX2 compile-time switch * coordinates: co, eo, epsep, cpsep_sym, cocpsep_sym, cphtr_sym, cocphtr_sym * pruning tables (1 bit per entry + fallback) diff --git a/benchmark/bench.c b/benchmark/bench.c @@ -1,11 +1,197 @@ #include <stdbool.h> #include <stdint.h> #include <stdio.h> +#include <stdlib.h> +#include <time.h> #include "../src/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); +} + +double +bench(void (*run)(void), void (*setup)(void), char *name) +{ + struct timespec start, end; + double tdiff, tdsec, tdnano; + + printf("\n"); + fflush(stdout); + + if (run == NULL) { + printf("> %s: nothing to run!\n", name); + fflush(stdout); + 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(); + clock_gettime(CLOCK_MONOTONIC, &end); + tdsec = end.tv_sec - start.tv_sec; + tdnano = end.tv_nsec - start.tv_nsec; + tdiff = tdsec + 1e-9 * tdnano; + printf("> %s: %.4fs\n", name, tdiff); + fflush(stdout); + + return tdiff; +} + int main() { - printf("Benchmarks not yet set up\n"); + double tmoves, ttrans, tcomp, tinv; + + printf( + "Benchmarks settings:\n" + "MOVES:\t%d\nTRANS:\t%d\nCOMP:\t%d\nINV:\t%d\n", + MOVES, TRANS, COMP, INV + ); + 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"); + + 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 + ); return 0; } diff --git a/benchmark/bench.sh b/benchmark/bench.sh @@ -7,6 +7,8 @@ CUBEOBJ="cube.o" cc -std=c99 -pthread -O3 -o $BENCHBIN benchmark/bench.c $CUBEOBJ || exit 1; $BENCHBIN | tee $BENCHOUT + +echo "" echo "Results saved to $BENCHOUT" rm -rf $BENCHBIN $CUBEOBJ