From ee84f9fe1faef1a8abe40134fabe0da1b8c1cc41 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Wed, 7 Jun 2023 17:30:17 -0400 Subject: [PATCH] 4-way branchless binary search unrolling --- src/singeli/src/bins.singeli | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/singeli/src/bins.singeli b/src/singeli/src/bins.singeli index a659f31e..f7a24b53 100644 --- a/src/singeli/src/bins.singeli +++ b/src/singeli/src/bins.singeli @@ -4,16 +4,24 @@ 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} + # Take a list of indices in x/res to allow unrolling + def search{inds} = { + xs:= each{bind{load,x}, inds} # Values + ss:= each{{_}=>ws, inds} # Initial lower bound + l := l0; h := undefined{u64} # Interval size l, same for all values while ((h=l/2) > 0) { - m := s + h - if (not lt{x, load{m}}) s = m + # Branchless update + def bin1{s, x, m} = { if (not lt{x, load{m}}) s = m } + each{bin1, ss, xs, each{bind{+,h}, ss}} l -= h } - res = cast_i{i32, s - ws} + each{{r,s} => store{res, r, cast_i{i32, s - ws}}, inds, 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}} } fn bins_branchless{T, up}(w:*void, wn:u64, x:*void, xn:u64, r:*i32) : void = {