Skip to content

Commit

Permalink
Improving iterator using prefetch
Browse files Browse the repository at this point in the history
Signed-off-by: NadavGigi <[email protected]>
  • Loading branch information
NadavGigi committed Jan 8, 2025
1 parent 8af35a1 commit 2125fbe
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/hashtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,47 @@ static inline incrementalFind *incrementalFindFromOpaque(hashtableIncrementalFin
return (incrementalFind *)(void *)state;
}

static void prefetchBucketEntries(bucket *b) {
for (int pos = 0; pos < numBucketPositions(b); pos++) {
if (isPositionFilled(b, pos)) {
valkey_prefetch(b->entries[pos]);
}
}
}

static bucket *getNextBucket(bucket *current_bucket, size_t bucket_index, hashtable *ht, int table_index) {
if (current_bucket->chained) {
return bucketNext(current_bucket);
} else {
size_t table_size = numBuckets(ht->bucket_exp[table_index]);
size_t next_index = bucket_index + 1;
if (next_index < table_size) {
return &ht->tables[table_index][next_index];
}
}
return NULL;
}

/* Attempts to bring the entries of the next bucket and the next next bucket structure closer to the L1 cache.
* While the iterator retrieving the entries of the current bucket, this function aims to
* reduce memory access latency by prefetching data likely to be needed soon.
*
* Cache state when this function is called:
* 1. The current bucket and its entries are likely already in cache.
* 2. The structure of the next bucket is in cache due to last prefetching call,
* ensuring low latency when accessing it. */
static void prefetchNextBucketEntries(iter *iter, bucket *current_bucket) {
size_t next_index = iter->index + 1;
bucket *next_bucket = getNextBucket(current_bucket, next_index, iter->hashtable, iter->table);
if (next_bucket) {
prefetchBucketEntries(next_bucket);
bucket *next_next_bucket = getNextBucket(next_bucket, next_index + 1, iter->hashtable, iter->table);
if (next_next_bucket) {
valkey_prefetch(next_next_bucket);
}
}
}

/* --- API functions --- */

/* Allocates and initializes a new hashtable specified by the given type. */
Expand Down Expand Up @@ -1890,6 +1931,9 @@ int hashtableNext(hashtableIterator *iterator, void **elemptr) {
}
}
bucket *b = iter->bucket;
if (iter->pos_in_bucket == 0) {
prefetchNextBucketEntries(iter, b);
}
if (!isPositionFilled(b, iter->pos_in_bucket)) {
/* No entry here. */
continue;
Expand Down

0 comments on commit 2125fbe

Please sign in to comment.