From c08f4fd3833166367fc7dc83b668b32025bc2996 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 10 Apr 2024 16:02:34 -0700 Subject: [PATCH] Bucket scan optimization --- src/native/containers/dn-simdhash-specialization.h | 13 +++++++------ src/native/containers/dn-simdhash-test.c | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/native/containers/dn-simdhash-specialization.h b/src/native/containers/dn-simdhash-specialization.h index ed7f5258a4a129..a605fa665dd1b3 100644 --- a/src/native/containers/dn-simdhash-specialization.h +++ b/src/native/containers/dn-simdhash-specialization.h @@ -146,12 +146,14 @@ DN_SIMDHASH_SCAN_BUCKET_INTERNAL (DN_SIMDHASH_T_PTR hash, bucket_t *bucket, DN_S #else uint32_t index = find_first_matching_suffix(search_vector, bucket_suffixes, count); #endif - DN_SIMDHASH_KEY_T *key = &bucket->keys[index]; - - for (; index < count; index++, key++) { + for (; index < count; index++) { // FIXME: Could be profitable to manually hoist the data load outside of the loop, // if not out of SCAN_BUCKET_INTERNAL entirely. Clang appears to do LICM on it. - if (DN_SIMDHASH_KEY_EQUALS(DN_SIMDHASH_GET_DATA(hash), needle, *key)) + // It's better to index bucket->keys each iteration inside the loop than to precompute + // a pointer outside and bump the pointer, because in many cases the bucket will be + // empty, and in many other cases it will have one match. Putting the index inside the + // loop means that for empty/no-match buckets we don't do the index calculation at all. + if (DN_SIMDHASH_KEY_EQUALS(DN_SIMDHASH_GET_DATA(hash), needle, bucket->keys[index])) return index; } @@ -170,12 +172,11 @@ DN_SIMDHASH_SCAN_BUCKET_INTERNAL (DN_SIMDHASH_T_PTR hash, bucket_t *bucket, DN_S #define END_SCAN_BUCKETS(initial_index, bucket_index, bucket_address) \ bucket_index++; \ + bucket_address++; \ /* Wrap around if we hit the last bucket. */ \ if (bucket_index >= buffers.buckets_length) { \ bucket_index = 0; \ bucket_address = address_of_bucket(buffers, 0); \ - } else { \ - bucket_address++; \ } \ /* if bucket_index == initial_index, we reached our starting point */ \ } while (bucket_index != initial_index); \ diff --git a/src/native/containers/dn-simdhash-test.c b/src/native/containers/dn-simdhash-test.c index df7bd6e74c2de2..36bfe9edfab6a7 100644 --- a/src/native/containers/dn-simdhash-test.c +++ b/src/native/containers/dn-simdhash-test.c @@ -17,7 +17,7 @@ typedef struct { float f; } instance_data_t; -static inline uint8_t +static DN_FORCEINLINE(uint8_t) key_comparer (instance_data_t data, size_t lhs, size_t rhs) { return ((data.f == 4.20f) || (lhs == rhs)); }