aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-04-01 10:11:50 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-04-01 10:11:50 +0200
commit2cff8fe8f8d18d0d6ed51d5a25b43b20ddf20901 (patch)
tree8a6392cfc78266c1b01830ce4a94f3dc1c90d0e0
parentd46f5be9da49b4f353ac1aa09cc54c223f4fe5b5 (diff)
downloadnissy-core-2cff8fe8f8d18d0d6ed51d5a25b43b20ddf20901.tar.gz
nissy-core-2cff8fe8f8d18d0d6ed51d5a25b43b20ddf20901.zip
Performance improvement for gendata_cocsep
-rw-r--r--.gitignore1
-rw-r--r--Makefile3
-rw-r--r--TODO.txt1
-rw-r--r--cube.c50
-rw-r--r--old/gendata_bfs_attempt.c153
5 files changed, 185 insertions, 23 deletions
diff --git a/.gitignore b/.gitignore
index d47841b..0191ea5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ test/*/runtest
7test/run 7test/run
8test/last.* 8test/last.*
9*.o 9*.o
10*.s
diff --git a/Makefile b/Makefile
index 4afb030..c51be91 100644
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,9 @@ include config.mk
2 2
3all: cube.o debugcube.o 3all: cube.o debugcube.o
4 4
5cube.s: clean
6 ${CC} -D${CUBETYPE} ${CFLAGS} -c -S -o cube.s cube.c
7
5cube.o: clean 8cube.o: clean
6 ${CC} -D${CUBETYPE} ${CFLAGS} -c -o cube.o cube.c 9 ${CC} -D${CUBETYPE} ${CFLAGS} -c -o cube.o cube.c
7 10
diff --git a/TODO.txt b/TODO.txt
index 7cb5169..e0ea12d 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,4 +1,3 @@
1TODO optimize cocsep generation (very slow!)
2TODO check which is faster: foreach_move or simple for loop? 1TODO check which is faster: foreach_move or simple for loop?
3 same for transformations 2 same for transformations
4TODO implement big pruning table for H48 solver 3TODO implement big pruning table for H48 solver
diff --git a/cube.c b/cube.c
index c3c03f8..c3f2b6a 100644
--- a/cube.c
+++ b/cube.c
@@ -1075,6 +1075,7 @@ previous sections, while some other operate directly on the cube.
1075 invertco_fast(compose_fast(compose_fast(_trans_cube_ ## T, c), \ 1075 invertco_fast(compose_fast(compose_fast(_trans_cube_ ## T, c), \
1076 _trans_cube_ ## T ## _inverse)) 1076 _trans_cube_ ## T ## _inverse))
1077 1077
1078/*
1078#define _foreach_move(_m, _c, _d, instruction) \ 1079#define _foreach_move(_m, _c, _d, instruction) \
1079 _m = U; _d = _move(U, _c); instruction \ 1080 _m = U; _d = _move(U, _c); instruction \
1080 _m = U2; _d = _move(U2, _c); instruction \ 1081 _m = U2; _d = _move(U2, _c); instruction \
@@ -1094,10 +1095,9 @@ previous sections, while some other operate directly on the cube.
1094 _m = B; _d = _move(B, _c); instruction \ 1095 _m = B; _d = _move(B, _c); instruction \
1095 _m = B2; _d = _move(B2, _c); instruction \ 1096 _m = B2; _d = _move(B2, _c); instruction \
1096 _m = B3; _d = _move(B3, _c); instruction 1097 _m = B3; _d = _move(B3, _c); instruction
1097/* 1098*/
1098#define _foreach_move(_m, _c, _d, instruction) \ 1099#define _foreach_move(_m, _c, _d, instruction) \
1099 for (_m = 0; _m < 18; _m++) { _d = move(_c, _m); instruction } 1100 for (_m = 0; _m < 18; _m++) { _d = move(_c, _m); instruction }
1100*/
1101 1101
1102cube_t solvedcube(void); 1102cube_t solvedcube(void);
1103bool isconsistent(cube_t); 1103bool isconsistent(cube_t);
@@ -1867,7 +1867,8 @@ Section: auxiliary procedures for H48 optimal solver (temporary)
1867******************************************************************************/ 1867******************************************************************************/
1868 1868
1869_static size_t gendata_cocsep(void *); 1869_static size_t gendata_cocsep(void *);
1870_static uint32_t dfs_cocsep(cube_fast_t, uint8_t, uint8_t, uint16_t *, uint32_t *); 1870_static uint32_t dfs_cocsep(
1871 cube_fast_t, uint8_t, uint8_t, uint16_t *, uint32_t *, bool *);
1871 1872
1872/* 1873/*
1873Each element of the cocsep table is a uint32_t used as follows: 1874Each element of the cocsep table is a uint32_t used as follows:
@@ -1883,33 +1884,36 @@ After the data as described above, more auxiliary information is appended:
1883_static size_t 1884_static size_t
1884gendata_cocsep(void *buf) 1885gendata_cocsep(void *buf)
1885{ 1886{
1887 static size_t tablesize = _3p7 << 7U;
1888
1889 cube_fast_t solved;
1886 uint32_t *buf32, cc; 1890 uint32_t *buf32, cc;
1887 uint16_t n; 1891 uint16_t n;
1888 uint8_t i, j; 1892 uint8_t i, j;
1889 size_t tablesize; 1893 bool visited[tablesize];
1890
1891 tablesize = _3p7 << 7U;
1892 1894
1893 buf32 = (uint32_t *)buf; 1895 buf32 = (uint32_t *)buf;
1894 memset(buf32, 0xFFU, 4*tablesize); 1896 memset(buf32, 0xFFU, 4*tablesize);
1895 memset(buf32 + tablesize, 0, 21*4); 1897 memset(buf32 + tablesize, 0, 21*4);
1896 1898
1897 for (i = 0, n = 0, cc = 0; cc != 0 || i == 0; i++) { 1899 solved = cubetofast(solvedcube());
1900 buf32[tablesize+1] = 9U; /* Known max pruning value */
1901 for (i = 0, n = 0, cc = 0; i < 10; i++) {
1902 memset(visited, 0, tablesize); /* Set visited bit for dfs */
1898 DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i); 1903 DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i);
1899 cc = dfs_cocsep(cubetofast(solvedcube()), 0, i, &n, buf32); 1904 cc = dfs_cocsep(solved, 0, i, &n, buf32, visited);
1900 buf32[tablesize+i+2] = cc; 1905 buf32[tablesize+i+2] = cc;
1901 DBG_LOG("found %" PRIu32 "\n", cc); 1906 DBG_LOG("found %" PRIu32 "\n", cc);
1902 } 1907 }
1903 buf32[tablesize] = (uint32_t)n; 1908 buf32[tablesize] = (uint32_t)n;
1904 buf32[tablesize+1] = (uint32_t)(i-2);
1905 1909
1906 DBG_LOG("cocsep data computed, %" PRIu32 " symmetry classes\n", n); 1910 DBG_LOG("cocsep data computed, %" PRIu32 " symmetry classes\n", n);
1907 DBG_LOG("Maximum pruning value: %" PRIu32 "\n", buf32[tablesize+1]); 1911 DBG_LOG("Maximum pruning value: %" PRIu32 "\n", buf32[tablesize+1]);
1908 DBG_LOG("Pruning value distribution:\n"); 1912 DBG_LOG("Pruning value distribution:\n");
1909 for (j = 0; j < i-1; j++) 1913 for (j = 0; j < 10; j++)
1910 DBG_LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, buf32[tablesize+j+2]); 1914 DBG_LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, buf32[tablesize+j+2]);
1911 1915
1912 return 4*(tablesize + i + 1); 1916 return 4*(tablesize + 12);
1913} 1917}
1914 1918
1915_static uint32_t 1919_static uint32_t
@@ -1918,25 +1922,31 @@ dfs_cocsep(
1918 uint8_t depth, 1922 uint8_t depth,
1919 uint8_t maxdepth, 1923 uint8_t maxdepth,
1920 uint16_t *n, 1924 uint16_t *n,
1921 uint32_t *buf32 1925 uint32_t *buf32,
1926 bool *visited
1922) 1927)
1923{ 1928{
1924 uint8_t m, t, tinv, olddepth; 1929 uint8_t m, t, tinv, olddepth;
1925 uint32_t cc, oldvalue; 1930 uint32_t cc;
1926 uint64_t i; 1931 uint64_t i;
1927 cube_fast_t d; 1932 cube_fast_t d;
1928 1933
1929 oldvalue = buf32[coord_fast_cocsep(c)]; 1934 i = coord_fast_cocsep(c);
1935 olddepth = (uint8_t)(buf32[i] & 0xFFU);
1936 if (olddepth < depth || visited[i])
1937 return 0;
1938 visited[i] = true;
1939
1930 if (depth == maxdepth) { 1940 if (depth == maxdepth) {
1931 if ((oldvalue & 0xFFU) != 0xFFU) 1941 if ((buf32[i] & 0xFFU) != 0xFFU)
1932 return 0; 1942 return 0;
1933 1943
1934 for (t = 0, cc = 0; t < 48; t++) { 1944 for (t = 0, cc = 0; t < 48; t++) {
1935 d = transform(c, t); 1945 d = transform(c, t);
1936 i = coord_fast_cocsep(d); 1946 i = coord_fast_cocsep(d);
1947 visited[i] = true;
1937 tinv = inverse_trans(t); 1948 tinv = inverse_trans(t);
1938 if ((buf32[i] & 0xFFU) == 0xFFU) 1949 cc += (buf32[i] & 0xFFU) == 0xFFU;
1939 cc++;
1940 buf32[i] = (*n << 16U) | (tinv << 8U) | depth; 1950 buf32[i] = (*n << 16U) | (tinv << 8U) | depth;
1941 } 1951 }
1942 (*n)++; 1952 (*n)++;
@@ -1944,13 +1954,9 @@ dfs_cocsep(
1944 return cc; 1954 return cc;
1945 } 1955 }
1946 1956
1947 olddepth = (uint8_t)(oldvalue & 0xFFU);
1948 if (olddepth != depth)
1949 return 0;
1950
1951 cc = 0; 1957 cc = 0;
1952 _foreach_move(m, c, d, 1958 _foreach_move(m, c, d,
1953 cc += dfs_cocsep(d, depth+1, maxdepth, n, buf32); 1959 cc += dfs_cocsep(d, depth+1, maxdepth, n, buf32, visited);
1954 ) 1960 )
1955 1961
1956 return cc; 1962 return cc;
diff --git a/old/gendata_bfs_attempt.c b/old/gendata_bfs_attempt.c
new file mode 100644
index 0000000..4cd5ae9
--- /dev/null
+++ b/old/gendata_bfs_attempt.c
@@ -0,0 +1,153 @@
1_static size_t gendata_cocsep(void *);
2_static uint32_t dfs_cocsep(cube_fast_t, uint8_t, uint8_t, uint32_t *);
3
4/*
5Each element of the cocsep table is a uint32_t used as follows:
6 - Lowest 8-bit block: pruning value
7 - Second-lower 8-bit block: "ttrep" (transformation to representative)
8 - Top 16-bit block: symcoord value
9After the data as described above, more auxiliary information is appended:
10 - A uint32_t representing the number of symmetry classes
11 - A uint32_t representing the highest value of the pruning table
12 - One uint32_t for each "line" of the pruning table, representing the number
13 of positions having that pruning value.
14*/
15_static size_t
16gendata_cocsep(void *buf)
17{
18 uint32_t *buf32, cc;
19 uint64_t i64;
20 uint16_t n;
21 uint8_t i, j;
22 size_t tablesize;
23
24 tablesize = _3p7 << 7U;
25
26 buf32 = (uint32_t *)buf;
27 memset(buf32, 0xFFU, 4*tablesize);
28 memset(buf32 + tablesize, 0, 21*4);
29
30/* New impl BFS
31
32 uint32_t nold = 0, nnew = 0;
33 uint64_t coord;
34 uint8_t m, olddepth;
35 cube_fast_t c, d, oldlevel[100000], newlevel[100000];
36 newlevel[0] = cubetofast(solvedcube());
37 nnew = 1;
38 buf32[coord_fast_cocsep(newlevel[0])] = UFr << 8U;
39 n = 1;
40 DBG_LOG("gendata_cocsep: found 1 position at depth 0\n");
41 for (i = 1; i < 10; i++) {
42 DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i);
43 memcpy(oldlevel, newlevel, nnew * sizeof(cube_fast_t));
44 nold = nnew;
45 nnew = 0;
46 for (j = 0; j < nold; j++) {
47 _foreach_move(m, oldlevel[j], newlevel[nnew],
48 coord = coord_fast_cocsep(newlevel[nnew]);
49 olddepth = buf32[coord] & 0xFFU;
50 buf32[coord] = i;
51 nnew += olddepth > i;
52 )
53 }
54 DBG_LOG("found %" PRIu32 "\n", nnew);
55 }
56
57End new impl BFS */
58
59 /* Pruning values */
60 buf32[tablesize+1] = 9U; /* Known max pruning value */
61 for (i = 0, cc = 0; i < 10; i++) {
62 DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i);
63 cc = dfs_cocsep(cubetofast(solvedcube()), 0, i, buf32);
64 buf32[tablesize+i+2] = cc;
65 DBG_LOG("found %" PRIu32 "\n", cc);
66 }
67
68 /* Symmetries */
69 for (i64 = 0, n = 0; i64 < tablesize; i64++) {
70 }
71 buf32[tablesize] = (uint32_t)n;
72
73 DBG_LOG("cocsep data computed, %" PRIu32 " symmetry classes\n", n);
74 DBG_LOG("Maximum pruning value: %" PRIu32 "\n", buf32[tablesize+1]);
75 DBG_LOG("Pruning value distribution:\n");
76 for (j = 0; j < 10; j++)
77 DBG_LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, buf32[tablesize+j+2]);
78
79 return 4*(tablesize + 11);
80}
81
82_static uint32_t
83dfs_cocsep(cube_fast_t c, uint8_t depth, uint8_t maxdepth, uint32_t *buf32)
84{
85 uint8_t m, olddepth;
86 uint32_t update, cc;
87 uint64_t i;
88 cube_fast_t d;
89
90 i = coord_fast_cocsep(c);
91 olddepth = (uint8_t)(buf32[i] & 0xFFU);
92 if (olddepth < depth)
93 return 0;
94
95 if (depth == maxdepth) {
96 update = (buf32[i] & 0xFFU) == 0xFFU;
97 buf32[i] = depth;
98 return update;
99 }
100
101 cc = 0;
102 _foreach_move(m, c, d,
103 cc += dfs_cocsep(d, depth+1, maxdepth, buf32);
104 )
105
106 return cc;
107}
108
109/*
110_static uint32_t
111dfs_cocsep(
112 cube_fast_t c,
113 uint8_t depth,
114 uint8_t maxdepth,
115 uint16_t *n,
116 uint32_t *buf32
117)
118{
119 uint8_t m, t, tinv, olddepth;
120 uint32_t cc, oldvalue;
121 uint64_t i;
122 cube_fast_t d;
123
124 oldvalue = buf32[coord_fast_cocsep(c)];
125 if (depth == maxdepth) {
126 if ((oldvalue & 0xFFU) != 0xFFU)
127 return 0;
128
129 for (t = 0, cc = 0; t < 48; t++) {
130 d = transform(c, t);
131 i = coord_fast_cocsep(d);
132 tinv = inverse_trans(t);
133 if ((buf32[i] & 0xFFU) == 0xFFU)
134 cc++;
135 buf32[i] = (*n << 16U) | (tinv << 8U) | depth;
136 }
137 (*n)++;
138
139 return cc;
140 }
141
142 olddepth = (uint8_t)(oldvalue & 0xFFU);
143 if (olddepth != depth)
144 return 0;
145
146 cc = 0;
147 _foreach_move(m, c, d,
148 cc += dfs_cocsep(d, depth+1, maxdepth, n, buf32);
149 )
150
151 return cc;
152}
153*/

Generated with cgit - Back to sebastiano.tronto.net