From 876914d0532c6712042f34cf21ed035f54b061b9 Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 6 Apr 2023 14:39:03 +0300 Subject: [PATCH] Singeli single-element search --- build/src/build.bqn | 1 + src/builtins/search.c | 20 ++++++++++++++++---- src/singeli/src/base.singeli | 11 +++++++++-- src/singeli/src/bmi2.singeli | 2 -- src/singeli/src/search.singeli | 27 +++++++++++++++++++++++++++ 5 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 src/singeli/src/search.singeli diff --git a/build/src/build.bqn b/build/src/build.bqn index 46468f1d..3fe9e2ad 100755 --- a/build/src/build.bqn +++ b/build/src/build.bqn @@ -595,6 +595,7 @@ cachedBin‿linkerCache ← { "xa."‿"src/builtins/arithd.c"‿"dyarith", "xa."‿"src/builtins/cmp.c"‿"cmp", "xa."‿"src/builtins/squeeze.c"‿"squeeze", "xa."‿"src/utils/mut.c"‿"copy", "xa."‿"src/utils/bits.c"‿"bits", "xag"‿"src/builtins/transpose.c"‿"transpose", + "xa."‿"src/builtins/search.c"‿"search", "2.."‿"src/builtins/select.c"‿"select", "2.."‿"src/builtins/scan.c"‿"scan", "2.."‿"src/builtins/fold.c"‿"fold", "2.."‿"src/builtins/slash.c"‿"slash", diff --git a/src/builtins/search.c b/src/builtins/search.c index 2a691c39..0345ac67 100644 --- a/src/builtins/search.c +++ b/src/builtins/search.c @@ -132,6 +132,11 @@ static B reduceI32Width(B r, usz count) { return count<=I8_MAX? taga(cpyI8Arr(r)) : count<=I16_MAX? taga(cpyI16Arr(r)) : r; } +#if SINGELI_SIMD + #define SINGELI_FILE search + #include "../utils/includeSingeli.h" +#endif + static NOINLINE usz indexOfOne(B l, B e) { void* lp = tyany_ptr(l); usz wia = IA(l); @@ -158,10 +163,17 @@ static NOINLINE usz indexOfOne(B l, B e) { } } - chk8: for (ux i=0; i>1<<1) == n & n>0} = lb{n>>1}+1 @@ -31,6 +37,7 @@ def rare{x & knum{x}} = x def rare{x:u1} = emit{u1, '__builtin_expect', x, 0} def assert{x & x==0} = assert{'failed assertion'} def assert{x & x==1} = 1 +def unreachable{} = emit{void, '__builtin_unreachable'} def assert{x:u1} = { if (not x) emit{void, '__builtin_unreachable'} } # various checks diff --git a/src/singeli/src/bmi2.singeli b/src/singeli/src/bmi2.singeli index cfb6c24b..3fdcb7b0 100644 --- a/src/singeli/src/bmi2.singeli +++ b/src/singeli/src/bmi2.singeli @@ -2,8 +2,6 @@ def pdep{x:u64, m:u64} = emit{u64, '_pdep_u64', x, m} def pdep{x:u32, m:u32} = emit{u32, '_pdep_u32', x, m} def pext{x:u64, m:u64} = emit{u64, '_pext_u64', x, m} def pext{x:u32, m:u32} = emit{u32, '_pext_u32', x, m} -def popc{x:T & isint{T} & width{T}==64} = emit{u8, '__builtin_popcountll', x} -def popc{x:T & isint{T} & width{T}<=32} = emit{u8, '__builtin_popcount', x} def popcRand{x:T & isint{T} & width{T}==64} = emit{u8, 'rand_popc64', x} # under valgrind, return a random result in the range of possible ones def popcRand{x:T & isint{T} & width{T}<=32} = emit{u8, 'rand_popc64', x} diff --git a/src/singeli/src/search.singeli b/src/singeli/src/search.singeli new file mode 100644 index 00000000..99b09e8e --- /dev/null +++ b/src/singeli/src/search.singeli @@ -0,0 +1,27 @@ +include './base' +if (hasarch{'AVX2'}) { + include './sse' + include './avx' + include './avx2' +} else if (hasarch{'X86_64'}) { + include './sse2' +} else if (hasarch{'AARCH64'}) { + include './neon' +} +include './mask' + +fn search{A, E}(l:*void, e0:A, n:u64) : u64 = { + def e = if (A==E) e0 else cast_i{E, e0} + def bulk = arch_defvw/width{E} + def VT = [bulk]E + maskedLoop{bulk, n, {i, M} => { + eq:= loadBatch{*E~~l, i, VT} == VT**e + if (homAny{M{eq}}) return{i*bulk + promote{u64, ctz{homMask{eq}}}} + }} + n +} + +export{'simd_search_u8', search{u64, u8}} +export{'simd_search_u16', search{u64, u16}} +export{'simd_search_u32', search{u64, u32}} +export{'simd_search_f64', search{f64, f64}} \ No newline at end of file