diff --git a/src/native/containers/dn-simdhash-specialization.h b/src/native/containers/dn-simdhash-specialization.h index 1d7197933e30b5..ac454e894acb9d 100644 --- a/src/native/containers/dn-simdhash-specialization.h +++ b/src/native/containers/dn-simdhash-specialization.h @@ -22,6 +22,10 @@ #error Expected DN_SIMDHASH_VALUE_T definition i.e. int #endif +// If specified, we pass instance data to the handlers by-value, otherwise we +// pass the pointer to the hash itself by-value. This is enough to allow clang +// to hoist the load of the instance data out of the key scan loop, though it +// won't hoist it all the way out of the bucket scan loop. #ifndef DN_SIMDHASH_INSTANCE_DATA_T #define DN_SIMDHASH_GET_DATA(hash) (hash) #define DN_SIMDHASH_INSTANCE_DATA_T DN_SIMDHASH_T_PTR @@ -114,6 +118,8 @@ DN_SIMDHASH_SCAN_BUCKET_INTERNAL (DN_SIMDHASH_T_PTR hash, bucket_t *bucket, DN_S DN_SIMDHASH_KEY_T *key = &bucket->keys[index]; for (uint32_t count = dn_simdhash_bucket_count(suffixes); index < count; index++, key++) { + // 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)) return index; } diff --git a/src/native/containers/dn-simdhash-test.c b/src/native/containers/dn-simdhash-test.c index fb30ad8154d84b..a35327c4f3cb4d 100644 --- a/src/native/containers/dn-simdhash-test.c +++ b/src/native/containers/dn-simdhash-test.c @@ -10,11 +10,24 @@ #include "dn-vector.h" #include "dn-simdhash.h" +typedef struct { + int i; + float f; +} instance_data_t; + +static inline uint8_t +key_comparer (instance_data_t data, size_t lhs, size_t rhs) { + return ((data.f == 4.20f) || (lhs == rhs)); +} + #define DN_SIMDHASH_T dn_simdhash_size_t_size_t #define DN_SIMDHASH_KEY_T size_t #define DN_SIMDHASH_VALUE_T size_t -#define DN_SIMDHASH_KEY_HASHER(hash, key) (uint32_t)(key & 0xFFFFFFFFu) -#define DN_SIMDHASH_KEY_EQUALS(hash, lhs, rhs) (lhs == rhs) +#define DN_SIMDHASH_KEY_HASHER(data, key) (uint32_t)(key & 0xFFFFFFFFu) +#define DN_SIMDHASH_KEY_EQUALS key_comparer +#define DN_SIMDHASH_INSTANCE_DATA_T instance_data_t +#define DN_SIMDHASH_ON_REMOVE(data, key, value) ; // printf("remove [%zd, %zd], f==%f\n", key, value, data.f) +#define DN_SIMDHASH_ON_REPLACE(data, key, old_value, new_value) ; // printf("replace [%zd, %zd] with [%zd, %zd] i==%i\n", key, old_value, key, new_value, data.i) #include "dn-simdhash-specialization.h" @@ -56,6 +69,9 @@ void foreach_callback (size_t key, size_t value, void * user_data) { int main () { const int c = 10240; dn_simdhash_size_t_size_t_t *test = dn_simdhash_size_t_size_t_new(0, NULL); + dn_simdhash_instance_data(instance_data_t, test).f = 3.14f; + dn_simdhash_instance_data(instance_data_t, test).i = 42; + dn_vector_t *keys = dn_vector_alloc(sizeof(DN_SIMDHASH_KEY_T)), *values = dn_vector_alloc(sizeof(DN_SIMDHASH_VALUE_T)); // Ensure consistency between runs