diff options
| author | eunhhu <[email protected]> | 2026-10-08 11:28:07 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-10-08 11:28:07 +0100 |
| commit | d0558a3a728af8c6c0d8bef2ce7fa55565c518a5 (patch) | |
| tree | c213462dd867be69457178d0a22571e19519beda /core/module-list.c | |
| parent | 1b902056b7f2b68277534bcfbfa32d0808dbe05b (diff) | |
| download | pure-d0558a3a728af8c6c0d8bef2ce7fa55565c518a5.tar.gz pure-d0558a3a728af8c6c0d8bef2ce7fa55565c518a5.zip | |
Batch: general cuts (docs/research/131). A value computed by the same code as an earlier one in a line of the block (nothing between setting what it reads: planned at load, reuse_from and reuse_length) is taken from the earlier, kept for it; if !c { ... } one branch the other way, no NOT; an arm whose lanes are a quarter or fewer runs in those lanes alone (a selection: outer values gathered by sel, reductions into their lanes around, locals set given back masked at its end, stores and sums expanded, appends and a filter's kept rounds by sel; PURE_SELECT=all every straight arm, 0 none); a list whose keys are bits asked by them in one loop of lanes, a filter decided by its bits and bits of our own (no hash set; a key with no bit is not there); L.first + i affine while within the list; a slice's two bounds in one call (pure_list_slice); a filter's kept rounds copied from numbers made once. The suite's BFS 211 to 112 instructions an edge (the compiled code 38.5), 41.0 to 23.5 ms; the frontier sum 70 to 56 (35). Seeds 1, 2, 3, 5, 23 alike by default and with every arm selected
Diffstat (limited to 'core/module-list.c')
| -rw-r--r-- | core/module-list.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/core/module-list.c b/core/module-list.c index 3df710a..67fbbdb 100644 --- a/core/module-list.c +++ b/core/module-list.c @@ -2873,6 +2873,31 @@ size_t pure_list_bound(const PureList *list, unsigned field, PureCell key) { return pure_list_seek(list, field, key, &found); } +void pure_list_slice(const PureList *list, unsigned field, double low, double high, size_t *from, size_t *to) { + if (list->pack && (int)field == list->layout.key && list->count && list->pack->buckets && list->pack->whole && + fabs(low) < 0x1p53 && low == floor(low) && fabs(high) < 0x1p53 && high == floor(high)) { /* in integers: buckets by a shift */ + const Pack *pack = list->pack; + const double *keys = list->columns[list->layout.key]; + int64_t lo = (int64_t)low, hi = (int64_t)high; + size_t bounds[2], count = list->count; + for (unsigned side = 0; side < 2; ++side) { + int64_t whole = side ? hi : lo; + if (whole <= pack->low_whole) { bounds[side] = 0; continue; } + if (whole > pack->high_whole) { bounds[side] = count; continue; } + uint64_t at_whole = (uint64_t)(whole - pack->origin_whole), b = at_whole >> pack->shift; + size_t at = pack->first[b]; + if (b << pack->shift != at_whole) + for (size_t end = pack->first[b + 1]; at < end && keys[at] < (double)whole;) ++at; + bounds[side] = at; + } + *from = bounds[0], *to = bounds[1] < bounds[0] ? bounds[0] : bounds[1]; + return; + } + *from = pure_list_bound(list, field, (PureCell){.num = low}); + *to = pure_list_bound(list, field, (PureCell){.num = high}); + if (*to < *from) *to = *from; +} + /* An item where it is: its leaf and its place there. */ typedef struct { const Node *leaf; unsigned index; } Ref; |
