Generic Singeli version of 32-bit binary search

This commit is contained in:
Marshall Lochbaum 2023-06-06 20:04:39 -04:00
parent 6b5815dcc2
commit 464a53463d
4 changed files with 37 additions and 1 deletions

View File

@ -634,6 +634,7 @@ cachedBin‿linkerCache ← {
"xa.""src/builtins/squeeze.c""squeeze", "xa.""src/utils/mut.c""copy",
"xa.""src/utils/bits.c""bits", "xag""src/builtins/transpose.c""transpose",
"xag""src/builtins/search.c""search", "xa.""src/builtins/fold.c""fold",
"xag""src/builtins/sort.c""bins"
"2..""src/builtins/select.c""select", "2..""src/builtins/scan.c""scan",
"2..""src/builtins/slash.c""constrep", "2..""src/builtins/scan.c""neq",

View File

@ -370,13 +370,17 @@ B GRADE_CAT(c2)(B t, B w, B x) {
for (i64 i = 0; i < (i64)wia-1; i++) if (wi[i] GRADE_UD(>,<) wi[i+1]) thrM(GRADE_CHR": 𝕨 must be sorted"GRADE_UD(," in descending order"));
FL_SET(w, fl);
}
#if SINGELI
si_bins[2*2 + GRADE_UD(0,1)](wi, wia, xi, xia, rp);
#else
for (usz i = 0; i < xia; i++) {
i32 c = xi[i];
i32 *s = wi-1;
for (usz l = wia+1, h; (h=l/2)>0; l-=h) { i32* m = s+h; if (!(c LT *m)) s = m; }
rp[i] = s - (wi-1);
}
#endif
} else {
gen:;
SGetU(x)

View File

@ -3,6 +3,11 @@
// Defines Sort, Grade, and Bins
#if SINGELI
#define SINGELI_FILE bins
#include "../utils/includeSingeli.h"
#endif
#define CAT0(A,B) A##_##B
#define CAT(A,B) CAT0(A,B)
typedef struct BI32p { B k; i32 v; } BI32p;

View File

@ -0,0 +1,26 @@
include './base'
include 'util/tup'
def bin_search{lt, w, wn, x, n, res} = {
ws := w - 1
l0 := wn + 1
@for (x, res over n) {
s := ws
l := l0; h := undefined{u64}
while ((h=l/2) > 0) {
m := s + h
if (not lt{x, load{m}}) s = m
l -= h
}
res = cast_i{i32, s - ws}
}
}
fn bins_branchless{T, up}(w:*void, wn:u64, x:*void, xn:u64, r:*i32) : void = {
bin_search{if (up) <; else >, *T~~w, wn, *T~~x, xn, r}
}
exportT{
'si_bins',
join{table{bins_branchless, tup{i8,i16,i32,f64}, tup{1,0}}}
}