aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--src/cube.c26
2 files changed, 24 insertions, 8 deletions
diff --git a/README.md b/README.md
index a0d2ae2..2990c29 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,8 @@ $ make test
17 17
18* inline moves for avx2 18* inline moves for avx2
19* fix base get_ and set_ macros (constant arguments?) 19* fix base get_ and set_ macros (constant arguments?)
20* optimize things that use get_ and set_ 20* optimize inverse for avx2
21* other things to optimize?
21 22
22### Documentation and interface 23### Documentation and interface
23 24
@@ -38,12 +39,9 @@ $ make test
38 39
39### Things I need to learn: 40### Things I need to learn:
40 41
41* Use AVX2 instructions, in particular
42 [_mm256_shuffle_epi8](https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-10/mm256-shuffle-epi8.html))
43* Inspect compiled assembly 42* Inspect compiled assembly
44* Use valgrind tool cachegrind and other profiling tools 43* Use valgrind tool cachegrind and other profiling tools
45 44
46
47## Internal representation of the cube 45## Internal representation of the cube
48 46
49The plan (TODO) is to have multiple implementations: some that 47The plan (TODO) is to have multiple implementations: some that
diff --git a/src/cube.c b/src/cube.c
index 6eb49f0..73f50af 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -939,19 +939,36 @@ inverse(cube_t c)
939cube_t 939cube_t
940compose(cube_t c1, cube_t c2) 940compose(cube_t c1, cube_t c2)
941{ 941{
942 /* TODO: optimize for avx2 */
943 uint8_t i, piece1, piece2, p, orien, aux, auy;
944 cube_t ret; 942 cube_t ret;
945 943
946 setzero(ret);
947
948#ifdef DEBUG 944#ifdef DEBUG
949 if (!isconsistent(c1) || !isconsistent(c2)) { 945 if (!isconsistent(c1) || !isconsistent(c2)) {
950 fprintf(stderr, "compose error, inconsistent cube\n"); 946 fprintf(stderr, "compose error, inconsistent cube\n");
947 setzero(ret);
951 return ret; 948 return ret;
952 } 949 }
953#endif 950#endif
954 951
952#ifdef CUBE_AVX2
953 cube_t shuf, eo, eodone, co2, aux, auy1, auy2, cw, auz1, auz2, coclean;
954
955 co2 = _mm256_and_si256(c2, _co_avx2);
956 eo = _mm256_and_si256(c2, _eo_avx2);
957 shufd = _mm256_shuffle_epi8(c1, c2);
958 eodone = _mm256_(shufd, eo);
959 aux = _mm256_add_epi8(c1, co2);
960 cw = _mm256_set_epi64x(0, 0x2020202020202020, 0, 0);
961 auy1 = _mm256_add_epi8(aux, cw);
962 auy2 = _mm256_srli_si256(auy1, 2);
963 auz1 = _mm256_add_epi8(aux, auy2);
964 auz2 = _mm256_and_si256(auz1, _co_avx2);
965 coclean = _mm256_andnot_si256(eodone, _co_avx2);
966 ret = _mm256_or_si256(coclean, auz2);
967#else
968 uint8_t i, piece1, piece2, p, orien, aux, auy;
969
970 setzero(ret);
971
955 for (i = 0; i < 12; i++) { 972 for (i = 0; i < 12; i++) {
956 piece2 = get_edge(c2, i); 973 piece2 = get_edge(c2, i);
957 p = piece2 & _pbits; 974 p = piece2 & _pbits;
@@ -969,6 +986,7 @@ compose(cube_t c1, cube_t c2)
969 orien = (aux + auy) & _cobits2; 986 orien = (aux + auy) & _cobits2;
970 set_corner(ret, i, (piece1 & _pbits) | orien); 987 set_corner(ret, i, (piece1 & _pbits) | orien);
971 } 988 }
989#endif
972 990
973 return ret; 991 return ret;
974} 992}

Generated with cgit - Back to sebastiano.tronto.net