Singeli single-element search

This commit is contained in:
dzaima 2023-04-06 14:39:03 +03:00
parent a7e2d9ea17
commit 876914d053
5 changed files with 53 additions and 8 deletions

View File

@ -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",

View File

@ -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<wia; i++) { if ((( u8*)lp)[i]== v8 ) return i; } return wia;
chk16: for (ux i=0; i<wia; i++) { if (((u16*)lp)[i]==v16 ) return i; } return wia;
chk32: for (ux i=0; i<wia; i++) { if (((u32*)lp)[i]==v32 ) return i; } return wia;
chk64f: for (ux i=0; i<wia; i++) { if (((f64*)lp)[i]==v64f) return i; } return wia;
#if SINGELI_SIMD
chk8: return simd_search_u8 (lp, v8, wia);
chk16: return simd_search_u16(lp, v16, wia);
chk32: return simd_search_u32(lp, v32, wia);
chk64f: return simd_search_f64(lp, v64f, wia);
#else
chk8: for (ux i=0; i<wia; i++) { if ((( u8*)lp)[i]== v8 ) return i; } return wia;
chk16: for (ux i=0; i<wia; i++) { if (((u16*)lp)[i]==v16 ) return i; } return wia;
chk32: for (ux i=0; i<wia; i++) { if (((u32*)lp)[i]==v32 ) return i; } return wia;
chk64f: for (ux i=0; i<wia; i++) { if (((f64*)lp)[i]==v64f) return i; } return wia;
#endif
}
B indexOf_c2(B t, B w, B x) {

View File

@ -12,8 +12,14 @@ def exportT{name, fs} = { v:*type{tupsel{0,fs}} = fs; export{name, v} }
def elwidth{T} = width{eltype{T}}
# ceiling divide
def cdiv{a,b} = (a+b-1)/b
# more arith
def cdiv{a,b} = (a+b-1)/b # ceiling divide
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 ctz{x:T & isint{T} & width{T}==64} = emit{u8, '__builtin_ctzll', x}
def ctz{x:T & isint{T} & width{T}<=32} = emit{u8, '__builtin_ctz', x}
def clz{x:T & isint{T} & width{T}==64} = emit{u8, '__builtin_clzll', x}
def clz{x:T & isint{T} & width{T}<=32} = emit{u8, '__builtin_clz', x}
# base-2 log of a constant power of two
def lb{n & knum{n} & (n>>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

View File

@ -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}

View File

@ -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}}