From 1647e98fd2722ca5ee73fcb2d6911c7fa6b5a09d Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Sun, 13 Nov 2022 09:54:13 -0500 Subject: [PATCH] =?UTF-8?q?Use=20Singeli=20code=20for=20=E2=8D=8Bbool=20an?= =?UTF-8?q?d=20=E2=8D=92bool=20with=201-=20and=202-byte=20result?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/grade.h | 23 ++++++++--------------- src/builtins/slash.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/builtins/grade.h b/src/builtins/grade.h index 2ab47965..f59f73ec 100644 --- a/src/builtins/grade.h +++ b/src/builtins/grade.h @@ -202,16 +202,17 @@ B SORT_C1(B t, B x) { #endif -#define GRADE_CHR GRADE_UD("⍋","⍒") extern Arr* bitUD[3]; // from fns.c extern B bit2x[2]; +extern B grade_bool(B x, usz ia, bool up); // slash.c + +#define GRADE_CHR GRADE_UD("⍋","⍒") B GRADE_CAT(c1)(B t, B x) { if (isAtm(x) || RNK(x)==0) thrM(GRADE_CHR": Argument cannot be a unit"); if (RNK(x)>1) x = toCells(x); usz ia = IA(x); - if (ia>I32_MAX) thrM(GRADE_CHR": Argument too large"); + B r; if (ia<=2) { - B r; if (ia==2) { SGetU(x); r = incG(bit2x[!(compare(GetU(x,0), GetU(x,1)) GRADE_UD(<=,>=) 0)]); } else if (ia==1) r = taga(ptr_inc(bitUD[1])); else r = emptyIVec(); @@ -220,18 +221,10 @@ B GRADE_CAT(c1)(B t, B x) { } u8 xe = TI(x,elType); - i32* rp; B r = m_i32arrv(&rp, ia); - if (xe==el_bit) { - u64* xp = bitarr_ptr(x); - u64 sum = bit_sum(xp, ia); - u64 r0 = 0; - u64 r1 = GRADE_UD(ia-sum, sum); - for (usz i = 0; i < ia; i++) { - if (bitp_get(xp,i)^GRADE_UD(0,1)) rp[r1++] = i; - else rp[r0++] = i; - } - goto decG_sq; - } else if (xe==el_i8 && ia>8) { + if (xe==el_bit) return grade_bool(x, ia, GRADE_UD(1,0)); + if (ia>I32_MAX) thrM(GRADE_CHR": Argument too large"); + i32* rp; r = m_i32arrv(&rp, ia); + if (xe==el_i8 && ia>8) { i8* xp = i8any_ptr(x); usz n=ia; RADIX_SORT_i8(usz, GRADE); goto decG_sq; diff --git a/src/builtins/slash.c b/src/builtins/slash.c index 5755aef1..1687a102 100644 --- a/src/builtins/slash.c +++ b/src/builtins/slash.c @@ -413,6 +413,49 @@ static NOINLINE B zeroCells(B x) { // doesn't consume return r; } +B not_c1(B t, B x); +B grade_bool(B x, usz xia, bool up) { + #define BRANCHLESS_GRADE(T) \ + T* rp; r = m_##T##arrv(&rp, xia); \ + u64 r0 = 0; \ + u64 r1 = l0; \ + if (up) BG_LOOP(!) else BG_LOOP() + #define BG_LOOP(OP) \ + for (usz i = 0; i < xia; i++) { \ + bool b = OP bitp_get(xp,i); \ + rp[b?r0:r1-r0] = i; \ + r0+=b; r1++; \ + } + B r; + u64* xp = bitarr_ptr(x); + u64 sum = bit_sum(xp, xia); + u64 l0 = up? xia-sum : sum; // Length of first set of indices + #if SINGELI && defined(__BMI2__) + if (xia < 16) { BRANCHLESS_GRADE(i8) } + else if (xia <= 1<<15) { + B notx = not_c1(m_f64(0), inc(x)); + u64* xp0 = bitarr_ptr(notx); + u64* xp1 = xp; + if (!up) { u64* t=xp1; xp1=xp0; xp0=t; } + #define BMI_GRADE(W) \ + i##W* rp = m_tyarrvO(&r, W/8, xia, t_i##W##arr, W); \ + bmipopc_1slash##W(xp0, rp , xia); \ + bmipopc_1slash##W(xp1, rp+l0, xia); + if (xia <= 128) { BMI_GRADE(8) } else { BMI_GRADE(16) } + #undef BMI_GRADE + decG(notx); + } + #else + if (xia <= 128) { BRANCHLESS_GRADE(i8) } + else if (xia <= 1<<15) { BRANCHLESS_GRADE(i16) } + #endif + else if (xia <= 1ull<<31) { BRANCHLESS_GRADE(i32) } + else { BRANCHLESS_GRADE(f64) } + #undef BRANCHLESS_GRADE + #undef BG_LOOP + decG(x); return r; +} + void filter_ne_i32(i32* rp, i32* xp, usz len, usz sum, i32 val) { usz b = bsp_max; TALLOC(i16, buf, b + b/16); u64* wp = (u64*)(buf + b);