From bed2708537f5b5c7ef26fe3bffc83afc79a79ee2 Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 27 Oct 2022 18:49:56 +0300 Subject: [PATCH] move non-Singeli comparisons to function lookup --- src/builtins/cmp.c | 160 ++++++++++++++++++++++++++++++-------------- src/singeli/c/cmp.c | 73 ++------------------ test/cmp.bqn | 2 +- 3 files changed, 117 insertions(+), 118 deletions(-) diff --git a/src/builtins/cmp.c b/src/builtins/cmp.c index 33cf6b41..2b9fe6de 100644 --- a/src/builtins/cmp.c +++ b/src/builtins/cmp.c @@ -1,6 +1,16 @@ #include "../core.h" #include "../utils/each.h" +static NOINLINE void fillBits(u64* dst, u64 sz, bool v) { + u64 x = 0-(u64)v; + u64 am = (sz+63)/64; assert(am>0); + for (usz i = 0; i < am; i++) dst[i] = x; +} +static NOINLINE void fillBitsDec(u64* dst, u64 sz, bool v, u64 x) { + dec(b(x)); + fillBits(dst, sz, v); +} + static NOINLINE u8 aMakeEq(B* w, B* x, u8 we, u8 xe) { // returns el_MAX if failed B* p = we , wv & ~xv) CMP_AA_C1(gt, > ) + CMP_AA(ge, >=, wv | ~xv) CMP_AA_C1(ge, >=) + #undef CMP_AA + + + #define CMP_SLOW(T, GW) void cmp_slow_##T(void* r, void* w, B x, u64 l, BBB2B fn) { \ + assert(l>0); incBy(x,l-1); \ + for (usz i=0; i0); B x=b(xr); \ + if (LIKELY(q_##Q(x))) BODY; \ + else SLOW(N, T); \ + } + + #define CMP_SA1(N, T, Q, C, SLOW, OP) CMP_SA0(N, T, Q, SLOW, ({T xv = C(x); for (usz i=0; i=, CMP_TO_SLOW, wv | ~xv) + CMP_SA(lt, < , CMP_TO_SLOW, ~wv & xv) + CMP_SA(gt, > , CMP_TO_SLOW, wv & ~xv) + #undef CMP_SA + + FN_LUT(cmp_fns, base, eq, AS); FN_LUT(cmp_fns, base, eq, AA); + FN_LUT(cmp_fns, base, ne, AS); FN_LUT(cmp_fns, base, ne, AA); + FN_LUT(cmp_fns, base, gt, AS); FN_LUT(cmp_fns, base, gt, AA); + FN_LUT(cmp_fns, base, ge, AS); FN_LUT(cmp_fns, base, ge, AA); + FN_LUT(cmp_fns, base, lt, AS); + FN_LUT(cmp_fns, base, le, AS); +#endif +#undef FN_LUT + + + +#define AL(X) u64* rp; B r = m_bitarrc(&rp, X); usz ria=IA(r) +#define CMP_AA(CN, CR, NAME, PRE) NOINLINE B NAME##_AA(i32 swapped, B w, B x) { PRE \ u8 xe = TI(x, elType); if (xe==el_B) goto bad; \ u8 we = TI(w, elType); if (we==el_B) goto bad; \ if (RNK(w)==RNK(x)) { if (!eqShape(w, x)) thrF("%U: Expected equal shape prefix (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", swapped?CR:CN, swapped?x:w, swapped?w:x); \ - if (we!=xe) { B tw=w,tx=x; \ - we = aMakeEq(&tw, &tx, we, xe); \ - if (we==el_MAX) goto bad; \ - w=tw; x=tx; \ - } \ - AL(x) \ - switch(we) { default: UD; \ - case el_bit: { u64* wp=bitarr_ptr(w); u64* xp=bitarr_ptr(x); for(usz i=0;i", lt, < , ~wv & xv, ) -CMP_AA("=", "?", eq, ==, ~wv^xv, swapped=0;) -CMP_AA("≠", "?", ne, !=, wv^xv, swapped=0;) -#define ge_AA(T, W, X) le_AA(!T, X, W) -#define gt_AA(T, W, X) lt_AA(!T, X, W) +CMP_AA("≥", "≤", ge, ) +CMP_AA(">", "<", gt, ) +CMP_AA("=", "?", eq, swapped=0;) +CMP_AA("≠", "?", ne, swapped=0;) +#define le_AA(T, W, X) ge_AA(!T, X, W) +#define lt_AA(T, W, X) gt_AA(!T, X, W) #undef CMP_AA -#define CMP_SA(NAME, OP, BX, PRE) NOINLINE B NAME##_SA(i32 swapped, B w, B x) { PRE \ - u8 xe = TI(x, elType); if (xe==el_B) goto bad; AL(x) \ - switch(xe) { default: UD; \ - case el_bit: { if (!q_bit(w)) break; u64 wv=bitx(w); u64* xp=bitarr_ptr(x); for(usz i=0;i=, wv | ~xv, ) -CMP_SA(lt, < , ~wv & xv, ) -CMP_SA(gt, > , wv & ~xv, ) +CMP_SA(eq, eq, swapped=0;) +CMP_SA(ne, ne, swapped=0;) +CMP_SA(le, ge, ) +CMP_SA(ge, le, ) +CMP_SA(lt, gt, ) +CMP_SA(gt, lt, ) #undef CMP_SA - -#endif +#undef AL diff --git a/src/singeli/c/cmp.c b/src/singeli/c/cmp.c index 36a4e330..fbc17bb1 100644 --- a/src/singeli/c/cmp.c +++ b/src/singeli/c/cmp.c @@ -2,82 +2,21 @@ #include "../../core.h" #include "../../builtins.h" -static NOINLINE void fillBits(u64* dst, u64 sz, bool v) { - u64 x = 0-(u64)v; - u64 am = (sz+63)/64; assert(am>0); - for (usz i = 0; i < am; i++) dst[i] = x; -} -static NOINLINE void fillBitsDec(u64* dst, u64 sz, bool v, u64 x) { - dec(b(x)); - fillBits(dst, sz, v); -} - extern bool please_tail_call_err; static NOINLINE void cmp_err() { if (please_tail_call_err) thrM("Invalid comparison"); } #define BCALL(N, X) N(b(X)) #define interp_f64(X) b(X).f - #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #include "../gen/cmp.c" #pragma GCC diagnostic pop -typedef void (*CmpAAFn)(u64*, void*, void*, u64); -typedef void (*CmpASFn)(u64*, void*, u64, u64); -#define CMPFN(A,F,S,T) A##_##F##S##_##T -#define FN_LUT(A,F,S) static const Cmp##S##Fn lut_##A##_##F##S[] = {CMPFN(A,F,S,u1), CMPFN(A,F,S,i8), CMPFN(A,F,S,i16), CMPFN(A,F,S,i32), CMPFN(A,F,S,f64), CMPFN(A,F,S,u8), CMPFN(A,F,S,u16), CMPFN(A,F,S,u32)} +FN_LUT(cmp_fns, avx2, eq, AS); FN_LUT(cmp_fns, avx2, eq, AA); +FN_LUT(cmp_fns, avx2, ne, AS); FN_LUT(cmp_fns, avx2, ne, AA); +FN_LUT(cmp_fns, avx2, gt, AS); FN_LUT(cmp_fns, avx2, gt, AA); +FN_LUT(cmp_fns, avx2, ge, AS); FN_LUT(cmp_fns, avx2, ge, AA); +FN_LUT(cmp_fns, avx2, lt, AS); +FN_LUT(cmp_fns, avx2, le, AS); -FN_LUT(avx2, eq, AS); FN_LUT(avx2, eq, AA); -FN_LUT(avx2, ne, AS); FN_LUT(avx2, ne, AA); -FN_LUT(avx2, gt, AS); FN_LUT(avx2, gt, AA); -FN_LUT(avx2, ge, AS); FN_LUT(avx2, ge, AA); -FN_LUT(avx2, lt, AS); -FN_LUT(avx2, le, AS); -#undef FN_LUT - - -#define AL(X) u64* rp; B r = m_bitarrc(&rp, X); usz ria=IA(r) -#define CMP_AA(CN, CR, NAME, PRE) NOINLINE B NAME##_AA(i32 swapped, B w, B x) { PRE \ - u8 xe = TI(x, elType); if (xe==el_B) goto bad; \ - u8 we = TI(w, elType); if (we==el_B) goto bad; \ - if (RNK(w)==RNK(x)) { if (!eqShape(w, x)) thrF("%U: Expected equal shape prefix (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", swapped?CR:CN, swapped?x:w, swapped?w:x); \ - if (we!=xe) { B tw=w,tx=x; \ - we = aMakeEq(&tw, &tx, we, xe); \ - if (we==el_MAX) goto bad; \ - w=tw; x=tx; \ - } \ - AL(x); \ - if (ria) lut_avx2_##NAME##AA[we](rp, tyany_ptr(w), tyany_ptr(x), ria); \ - decG(w);decG(x); return r; \ - } \ - bad: return NAME##_rec(swapped, w, x); \ -} -CMP_AA("≥", "≤", ge, ) -CMP_AA(">", "<", gt, ) -CMP_AA("=", "?", eq, swapped=0;) -CMP_AA("≠", "?", ne, swapped=0;) -#define le_AA(T, W, X) ge_AA(!T, X, W) -#define lt_AA(T, W, X) gt_AA(!T, X, W) -#undef CMP_AA - - - - -#define CMP_SA(NAME, RNAME, PRE) B NAME##_SA(i32 swapped, B w, B x) { PRE \ - u8 xe = TI(x, elType); if (xe==el_B) goto bad; \ - AL(x); \ - if (ria) lut_avx2_##RNAME##AS[xe](rp, tyany_ptr(x), w.u, ria); \ - else dec(w); \ - decG(x); return r; \ - bad: return NAME##_rec(swapped, w, x); \ -} -CMP_SA(eq, eq, swapped=0;) -CMP_SA(ne, ne, swapped=0;) -CMP_SA(le, ge, ) -CMP_SA(ge, le, ) -CMP_SA(lt, gt, ) -CMP_SA(gt, lt, ) -#undef CMP_SA -#undef AL \ No newline at end of file diff --git a/test/cmp.bqn b/test/cmp.bqn index 836e2a74..9446fb8f 100644 --- a/test/cmp.bqn +++ b/test/cmp.bqn @@ -19,7 +19,7 @@ arrs ← •internal.Squeeze¨ ⟨ 65 (•MakeRand 2).Range 2 90 (•MakeRand 2).Range 2 ⟩ -atms ← 1‿¯1‿0‿¯0‿∞‿¯∞‿n‿nn‿@‿'l'‿'⍉'‿'𝕩'‿{a⇐1} +atms ← 1‿¯1‿0‿¯0‿∞‿¯∞‿n‿nn‿@‿'l'‿'⍉'‿'𝕩'‿{a⇐1}‿+‿{𝔽} atms∾↩ -⊸∾ 10⋆↕20 atms∾↩ -⊸∾ ⥊(⥊¯0.9‿¯0.1‿0‿0.1‿0.9+⌜2-↕5) +⌜ 2⋆↕35 atms∾↩ @+⥊128‿65536+⌜2-↕5