Singeli single-element search
This commit is contained in:
parent
a7e2d9ea17
commit
876914d053
@ -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",
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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}
|
||||
|
||||
27
src/singeli/src/search.singeli
Normal file
27
src/singeli/src/search.singeli
Normal 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}}
|
||||
Loading…
Reference in New Issue
Block a user