aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2023-11-19 10:45:37 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2023-11-19 10:45:37 +0100
commit15ceee3a7c72d174305fff9b4fe9886cb3f7204d (patch)
treefc2dc7280ccb581f49d8b123e5d7ea32673293a3
parent13275a4bb8696e730a4fffdd05b8e1d046e489c6 (diff)
downloadnissy-core-15ceee3a7c72d174305fff9b4fe9886cb3f7204d.tar.gz
nissy-core-15ceee3a7c72d174305fff9b4fe9886cb3f7204d.zip
Removed inverse_fast, probably not going to use it in tight loops
-rw-r--r--cube.c95
-rw-r--r--old/inverse_fast.c51
2 files changed, 75 insertions, 71 deletions
diff --git a/cube.c b/cube.c
index 558c094..ba72b45 100644
--- a/cube.c
+++ b/cube.c
@@ -134,6 +134,12 @@ Section: constants, strings and other stuff
134#define _eflip 0x10U 134#define _eflip 0x10U
135#define _error 0xFFU 135#define _error 0xFFU
136 136
137_static cube_t zero = { .corner = {0}, .edge = {0} };
138_static cube_t solved = {
139 .corner = {0, 1, 2, 3, 4, 5, 6, 7},
140 .edge = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
141};
142
137#define zero_fast fastcube( \ 143#define zero_fast fastcube( \
138 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
139#define solved_fast fastcube( \ 145#define solved_fast fastcube( \
@@ -507,7 +513,6 @@ _static_inline bool equal_fast(cube_fast_t, cube_fast_t);
507_static_inline bool issolved_fast(cube_fast_t); 513_static_inline bool issolved_fast(cube_fast_t);
508_static_inline cube_fast_t invertco_fast(cube_fast_t); 514_static_inline cube_fast_t invertco_fast(cube_fast_t);
509_static_inline cube_fast_t cleanaftershuffle(cube_fast_t); 515_static_inline cube_fast_t cleanaftershuffle(cube_fast_t);
510_static_inline cube_fast_t inverse_fast(cube_fast_t);
511_static_inline cube_fast_t compose_fast(cube_fast_t, cube_fast_t); 516_static_inline cube_fast_t compose_fast(cube_fast_t, cube_fast_t);
512_static_inline int64_t coord_fast_eo(cube_fast_t); 517_static_inline int64_t coord_fast_eo(cube_fast_t);
513 518
@@ -617,45 +622,6 @@ cleanaftershuffle(cube_fast_t c)
617} 622}
618 623
619_static_inline cube_fast_t 624_static_inline cube_fast_t
620inverse_fast(cube_fast_t c)
621{
622 /* Method taken from Andrew Skalski's vcube[1]. The addition sequence
623 * was generated using [2].
624 * [1] https://github.com/Voltara/vcube
625 * [2] http://wwwhomes.uni-bielefeld.de/achim/addition_chain.html
626 */
627 cube_fast_t v3, vi, vo, vp, ret;
628
629 v3 = _mm256_shuffle_epi8(c, c);
630 v3 = _mm256_shuffle_epi8(v3, c);
631 vi = _mm256_shuffle_epi8(v3, v3);
632 vi = _mm256_shuffle_epi8(vi, vi);
633 vi = _mm256_shuffle_epi8(vi, vi);
634 vi = _mm256_shuffle_epi8(vi, v3);
635 vi = _mm256_shuffle_epi8(vi, vi);
636 vi = _mm256_shuffle_epi8(vi, vi);
637 vi = _mm256_shuffle_epi8(vi, vi);
638 vi = _mm256_shuffle_epi8(vi, vi);
639 vi = _mm256_shuffle_epi8(vi, c);
640 vi = _mm256_shuffle_epi8(vi, vi);
641 vi = _mm256_shuffle_epi8(vi, vi);
642 vi = _mm256_shuffle_epi8(vi, vi);
643 vi = _mm256_shuffle_epi8(vi, vi);
644 vi = _mm256_shuffle_epi8(vi, vi);
645 vi = _mm256_shuffle_epi8(vi, v3);
646 vi = _mm256_shuffle_epi8(vi, vi);
647 vi = _mm256_shuffle_epi8(vi, c);
648
649 vo = _mm256_and_si256(c, _mm256_or_si256(_eo_avx2, _co2_avx2));
650 vo = _mm256_shuffle_epi8(vo, vi);
651 vp = _mm256_andnot_si256(_mm256_or_si256(_eo_avx2, _co2_avx2), vi);
652 ret = _mm256_or_si256(vp, vo);
653 ret = cleanaftershuffle(ret);
654
655 return invertco_fast(ret);
656}
657
658_static_inline cube_fast_t
659compose_fast(cube_fast_t c1, cube_fast_t c2) 625compose_fast(cube_fast_t c1, cube_fast_t c2)
660{ 626{
661 cube_fast_t ret; 627 cube_fast_t ret;
@@ -716,7 +682,6 @@ _static cube_t fasttocube(cube_fast_t);
716_static_inline bool equal_fast(cube_fast_t, cube_fast_t); 682_static_inline bool equal_fast(cube_fast_t, cube_fast_t);
717_static_inline bool issolved_fast(cube_fast_t); 683_static_inline bool issolved_fast(cube_fast_t);
718_static_inline cube_fast_t invertco_fast(cube_fast_t); 684_static_inline cube_fast_t invertco_fast(cube_fast_t);
719_static_inline cube_fast_t inverse_fast(cube_fast_t);
720_static_inline cube_fast_t compose_fast(cube_fast_t, cube_fast_t); 685_static_inline cube_fast_t compose_fast(cube_fast_t, cube_fast_t);
721_static_inline int64_t coord_fast_eo(cube_fast_t); 686_static_inline int64_t coord_fast_eo(cube_fast_t);
722 687
@@ -812,29 +777,6 @@ invertco_fast(cube_fast_t c)
812} 777}
813 778
814_static_inline cube_fast_t 779_static_inline cube_fast_t
815inverse_fast(cube_fast_t cube)
816{
817 cube_fast_t ret;
818 uint8_t i, piece, orien;
819
820 ret = zero_fast;
821
822 for (i = 0; i < 12; i++) {
823 piece = cube.edge[i];
824 orien = piece & _eobit;
825 ret.edge[piece & _pbits] = i | orien;
826 }
827
828 for (i = 0; i < 8; i++) {
829 piece = cube.corner[i];
830 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
831 ret.corner[piece & _pbits] = i | orien;
832 }
833
834 return ret;
835}
836
837_static_inline cube_fast_t
838compose_fast(cube_fast_t c1, cube_fast_t c2) 780compose_fast(cube_fast_t c1, cube_fast_t c2)
839{ 781{
840 cube_fast_t ret; 782 cube_fast_t ret;
@@ -895,12 +837,6 @@ previous sections, while some other operate directly on the cube.
895 invertco_fast(compose_fast(compose_fast(_trans_cube_ ## T, c), \ 837 invertco_fast(compose_fast(compose_fast(_trans_cube_ ## T, c), \
896 _trans_cube_ ## T ## _inverse)) 838 _trans_cube_ ## T ## _inverse))
897 839
898_static cube_t zero = { .corner = {0}, .edge = {0} };
899_static cube_t solved = {
900 .corner = {0, 1, 2, 3, 4, 5, 6, 7},
901 .edge = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
902};
903
904cube_t solvedcube(void); 840cube_t solvedcube(void);
905bool isconsistent(cube_t); 841bool isconsistent(cube_t);
906bool issolvable(cube_t); 842bool issolvable(cube_t);
@@ -1076,10 +1012,27 @@ compose(cube_t c1, cube_t c2)
1076cube_t 1012cube_t
1077inverse(cube_t cube) 1013inverse(cube_t cube)
1078{ 1014{
1015 cube_t ret;
1016 uint8_t i, piece, orien;
1017
1079 DBG_ASSERT(isconsistent(cube), zero, 1018 DBG_ASSERT(isconsistent(cube), zero,
1080 "inverse error: inconsistent cube\n"); 1019 "inverse error: inconsistent cube\n");
1081 1020
1082 return fasttocube(inverse_fast(cubetofast(cube))); 1021 ret = zero_fast;
1022
1023 for (i = 0; i < 12; i++) {
1024 piece = cube.edge[i];
1025 orien = piece & _eobit;
1026 ret.edge[piece & _pbits] = i | orien;
1027 }
1028
1029 for (i = 0; i < 8; i++) {
1030 piece = cube.corner[i];
1031 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
1032 ret.corner[piece & _pbits] = i | orien;
1033 }
1034
1035 return ret;
1083} 1036}
1084 1037
1085cube_t 1038cube_t
diff --git a/old/inverse_fast.c b/old/inverse_fast.c
new file mode 100644
index 0000000..13ace58
--- /dev/null
+++ b/old/inverse_fast.c
@@ -0,0 +1,51 @@
1_static_inline cube_fast_t
2cleanaftershuffle(cube_fast_t c)
3{
4 __m256i b;
5
6 b = _mm256_set_epi8(
7 ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0
9 );
10
11 return _mm256_andnot_si256(b, c);
12}
13
14_static_inline cube_fast_t
15inverse_fast(cube_fast_t c)
16{
17 /* Method taken from Andrew Skalski's vcube[1]. The addition sequence
18 * was generated using [2].
19 * [1] https://github.com/Voltara/vcube
20 * [2] http://wwwhomes.uni-bielefeld.de/achim/addition_chain.html
21 */
22 cube_fast_t v3, vi, vo, vp, ret;
23
24 v3 = _mm256_shuffle_epi8(c, c);
25 v3 = _mm256_shuffle_epi8(v3, c);
26 vi = _mm256_shuffle_epi8(v3, v3);
27 vi = _mm256_shuffle_epi8(vi, vi);
28 vi = _mm256_shuffle_epi8(vi, vi);
29 vi = _mm256_shuffle_epi8(vi, v3);
30 vi = _mm256_shuffle_epi8(vi, vi);
31 vi = _mm256_shuffle_epi8(vi, vi);
32 vi = _mm256_shuffle_epi8(vi, vi);
33 vi = _mm256_shuffle_epi8(vi, vi);
34 vi = _mm256_shuffle_epi8(vi, c);
35 vi = _mm256_shuffle_epi8(vi, vi);
36 vi = _mm256_shuffle_epi8(vi, vi);
37 vi = _mm256_shuffle_epi8(vi, vi);
38 vi = _mm256_shuffle_epi8(vi, vi);
39 vi = _mm256_shuffle_epi8(vi, vi);
40 vi = _mm256_shuffle_epi8(vi, v3);
41 vi = _mm256_shuffle_epi8(vi, vi);
42 vi = _mm256_shuffle_epi8(vi, c);
43
44 vo = _mm256_and_si256(c, _mm256_or_si256(_eo_avx2, _co2_avx2));
45 vo = _mm256_shuffle_epi8(vo, vi);
46 vp = _mm256_andnot_si256(_mm256_or_si256(_eo_avx2, _co2_avx2), vi);
47 ret = _mm256_or_si256(vp, vo);
48 ret = cleanaftershuffle(ret);
49
50 return invertco_fast(ret);
51}

Generated with cgit - Back to sebastiano.tronto.net