aboutsummaryrefslogtreecommitdiffstats
path: root/research/experiments/024-finding-items/prefetch.patch
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-30 13:52:30 +0100
committereunhhu <[email protected]>2026-09-30 13:52:30 +0100
commit68dca986ee7ff7d729a15565e2e07127d5b5d1a4 (patch)
tree89e50c693af9594c26320c56e37ee7f0f9b95d6a /research/experiments/024-finding-items/prefetch.patch
parentdacc3cf3e1e7fe6554575cefdb4ac6d7a19a61c6 (diff)
downloadpure-68dca986ee7ff7d729a15565e2e07127d5b5d1a4.tar.gz
pure-68dca986ee7ff7d729a15565e2e07127d5b5d1a4.zip
Say that prefetching items did not pay, and why (109)
Fetching a found item's cells, a leaf's keys and each level's keys ahead made finding and reading items 20% faster on 100,000 items in a micro benchmark, but TPC-C's clean pairs moved 1% at most and finding alone got 48% slower, so it is not in. The owner's finding samples were the descent, not the fields: a write right after a read copies the leaf whole anyway, and what costs is walking structures larger than the caches at random.
Diffstat (limited to 'research/experiments/024-finding-items/prefetch.patch')
-rw-r--r--research/experiments/024-finding-items/prefetch.patch21
1 files changed, 21 insertions, 0 deletions
diff --git a/research/experiments/024-finding-items/prefetch.patch b/research/experiments/024-finding-items/prefetch.patch
new file mode 100644
index 0000000..e642352
--- /dev/null
+++ b/research/experiments/024-finding-items/prefetch.patch
@@ -0,0 +1,21 @@
+--- a/core/module-list.c
++++ b/core/module-list.c
+@@ -1122,12 +1122,17 @@
+ unsigned taken = upper(g->keys + 1, FANOUT - 1, key.num);
+ start += g->before[taken];
+ node = child(node, taken);
++ if (!node->leaf)
++ for (unsigned i = 0; i < FANOUT; i += 8) __builtin_prefetch(guide(node)->keys + i);
+ }
+ const double *keys = numbers(l, node, field);
+- if (list->count > PREFETCHED) /* leaves past the caches: the leaf's keys fetched at once, not probe by probe */
++ if (true) /* the leaf's keys fetched at once, not probe by probe */
+ for (unsigned i = 0; i < node->count; i += 8) __builtin_prefetch(keys + i);
+ unsigned low = lower(keys, node->count, key.num);
+ *found = low < node->count && keys[low] == key.num;
++ if (*found) /* the item is read next, a field at a time: its cells, a line each, fetched together */
++ for (unsigned f = 0; f < l->fields; ++f)
++ __builtin_prefetch(l->text_fields[f] ? (const void *)&texts(l, node, f)[low] : (const void *)&numbers(l, node, f)[low]);
+ return start + low;
+ }
+ while (!node->leaf) {