Use type of ≠𝕨 for Singeli Bins result and allocate outside Singeli
This commit is contained in:
parent
e0621f99f8
commit
0346ff7c2d
@ -443,7 +443,9 @@ B GRADE_CAT(c2)(B t, B w, B x) {
|
||||
|
||||
#if SINGELI
|
||||
u8 k = elWidthLogBits(we) - 3;
|
||||
r = b(si_bins[k*2 + GRADE_UD(0,1)](tyany_ptr(w), wia, tyany_ptr(x), xia, x.u));
|
||||
u8 rl = wia<128 ? 0 : wia<(1<<15) ? 1 : wia<(1<<31) ? 2 : 3;
|
||||
void *rp = m_tyarrc(&r, 1<<rl, x, el2t(el_i8+rl));
|
||||
si_bins[k*2 + GRADE_UD(0,1)](tyany_ptr(w), wia, tyany_ptr(x), xia, rp, rl);
|
||||
#else
|
||||
i32* rp; r = m_i32arrc(&rp, x);
|
||||
i32* wi = tyany_ptr(w);
|
||||
|
||||
@ -5,11 +5,7 @@
|
||||
|
||||
#if SINGELI
|
||||
#define SINGELI_FILE bins
|
||||
#define m_i8arrc_wrapu(P, X) m_i8arrc(P, b(X)).u
|
||||
#define m_i32arrc_wrapu(P, X) m_i32arrc(P, b(X)).u
|
||||
#include "../utils/includeSingeli.h"
|
||||
#undef m_i8arrc_wrapu
|
||||
#undef m_i32arrc_wrapu
|
||||
#endif
|
||||
|
||||
#define CAT0(A,B) A##_##B
|
||||
|
||||
@ -119,7 +119,26 @@ def bin_search_vec{up, w:*i8, wn, x:*i8, n, res:*i8} = {
|
||||
}
|
||||
}
|
||||
|
||||
def bin_search_branchless{up, w, wn, x, n, res} = {
|
||||
def unroll_sizes = tup{4,1}
|
||||
def rtypes = tup{i8, i16, i32, f64}
|
||||
# Return index of smallest possible result type given max result value
|
||||
def get_rtype{len} = {
|
||||
t:u8 = 0
|
||||
def c{T, ...ts} = if (len>maxvalue{T}) { ++t; c{...ts} }
|
||||
def c{T==f64} = {}
|
||||
c{...rtypes}
|
||||
t
|
||||
}
|
||||
fn write{T,k}(r:*void, i:u64, ...vs:k**u64) : void = {
|
||||
each{{j,v} => store{*T~~r, i+j, cast_i{T,v}}, iota{k}, vs}
|
||||
}
|
||||
def make_wr{k} = {
|
||||
def w = each{{T} => write{T,k}, rtypes}
|
||||
a:*(type{tupsel{0,w}}) = w
|
||||
}
|
||||
def wr_arrs = each{make_wr, unroll_sizes}
|
||||
|
||||
def bin_search_branchless{up, w, wn, x, n, res, rtype} = {
|
||||
def lt = if (up) <; else >
|
||||
ws := w - 1
|
||||
l0 := wn + 1
|
||||
@ -134,33 +153,24 @@ def bin_search_branchless{up, w, wn, x, n, res} = {
|
||||
each{bin1, ss, xs, each{bind{+,h}, ss}}
|
||||
l -= h
|
||||
}
|
||||
each{{r,s} => store{res, r, cast_i{i32, s - ws}}, inds, ss}
|
||||
each{{s} => u64~~(s - ws), ss}
|
||||
}
|
||||
# Unroll by 4 then 1
|
||||
def search{i, k} = search{each{bind{+,i}, iota{k}}}
|
||||
j:u64 = 0
|
||||
def searches{k} = { while (j+k <= n) { search{j, k}; j+=k } }
|
||||
each{searches, tup{4, 1}}
|
||||
def searches{k, wr_arr} = {
|
||||
wr := load{wr_arr, rtype}
|
||||
while (j+k <= n) { wr(res, j, ...search{j, k}); j+=k }
|
||||
}
|
||||
each{searches, unroll_sizes, wr_arrs}
|
||||
}
|
||||
|
||||
def B = u64
|
||||
fn bins{T, up}(w:*void, wn:u64, x:*void, xn:u64, xb:B) : B = {
|
||||
def alloc{T,ts} = {
|
||||
u:*u64 = tup{0}
|
||||
rpp:* *T = (* *T)~~u
|
||||
r := emit{B, merge{'m_',ts,'arrc_wrapu'}, rpp, xb}
|
||||
rp := load{rpp,0}
|
||||
tup{r, rp}
|
||||
}
|
||||
r := undefined{B}
|
||||
fn bins{T, up}(w:*void, wn:u64, x:*void, xn:u64, rp:*void, rty:u8) : void = {
|
||||
if (T==i8 and wn<128 and xn>=32) {
|
||||
def {rt, rp} = alloc{i8, 'i8'}; r = rt
|
||||
bin_search_vec{up, *T~~w, wn, *T~~x, xn, rp}
|
||||
bin_search_vec{up, *T~~w, wn, *T~~x, xn, *i8~~rp}
|
||||
} else {
|
||||
def {rt, rp} = alloc{i32, 'i32'}; r = rt
|
||||
bin_search_branchless{up, *T~~w, wn, *T~~x, xn, rp}
|
||||
bin_search_branchless{up, *T~~w, wn, *T~~x, xn, rp, rty}
|
||||
}
|
||||
r
|
||||
}
|
||||
|
||||
exportT{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user