From 464a53463d9165773f7f56fb82c7300d03886e6a Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Tue, 6 Jun 2023 20:04:39 -0400 Subject: [PATCH] Generic Singeli version of 32-bit binary search --- build/src/build.bqn | 1 + src/builtins/grade.h | 6 +++++- src/builtins/sort.c | 5 +++++ src/singeli/src/bins.singeli | 26 ++++++++++++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/singeli/src/bins.singeli diff --git a/build/src/build.bqn b/build/src/build.bqn index 431342de..13a2818f 100755 --- a/build/src/build.bqn +++ b/build/src/build.bqn @@ -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", diff --git a/src/builtins/grade.h b/src/builtins/grade.h index d3878017..fffbe7f0 100644 --- a/src/builtins/grade.h +++ b/src/builtins/grade.h @@ -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) diff --git a/src/builtins/sort.c b/src/builtins/sort.c index 2684600d..e803ba21 100644 --- a/src/builtins/sort.c +++ b/src/builtins/sort.c @@ -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; diff --git a/src/singeli/src/bins.singeli b/src/singeli/src/bins.singeli new file mode 100644 index 00000000..a659f31e --- /dev/null +++ b/src/singeli/src/bins.singeli @@ -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}}} +}