util/hash_table: added hash functions for integer types

A few hash_table users roll their own integer hash functions which
call _mesa_hash_data to perform the hashing which ultimately calls
into XXH32 with a dynamic key length. When using small keys with a
constant size the hash rate can be greatly improved by inlining
XXH32 and providing it a constant key length, see:
https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html

Additionally, this patch removes calls to _mesa_key_hash_string and
makes them instead call _mesa_has_string directly, matching the new
integer hash functions.

Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3475>
This commit is contained in:
Anthony Pesch
2020-01-18 01:38:31 -05:00
committed by Marge Bot
parent 931388ceca
commit 1496cc92f6
20 changed files with 76 additions and 34 deletions

View File

@@ -168,7 +168,7 @@ lower_deref(nir_builder *b, struct lower_samplers_as_deref_state *state,
return deref;
}
uint32_t hash = _mesa_key_hash_string(name);
uint32_t hash = _mesa_hash_string(name);
struct hash_entry *h =
_mesa_hash_table_search_pre_hashed(state->remap_table, hash, name);
@@ -325,7 +325,7 @@ gl_nir_lower_samplers_as_deref(nir_shader *shader,
state.shader = shader;
state.shader_program = shader_program;
state.remap_table = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
state.remap_table = _mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
nir_foreach_function(function, shader) {

View File

@@ -1469,7 +1469,7 @@ glcpp_parser_create(struct gl_context *gl_ctx,
parser = ralloc (NULL, glcpp_parser_t);
glcpp_lex_init_extra (parser, &parser->scanner);
parser->defines = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
parser->defines = _mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
parser->linalloc = linear_alloc_parent(parser, 0);
parser->active = NULL;

View File

@@ -220,7 +220,7 @@ class interface_block_definitions
public:
interface_block_definitions()
: mem_ctx(ralloc_context(NULL)),
ht(_mesa_hash_table_create(NULL, _mesa_key_hash_string,
ht(_mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal))
{
}

View File

@@ -409,7 +409,7 @@ link_uniform_blocks(void *mem_ctx,
* the hash is organized by block-name.
*/
struct hash_table *block_hash =
_mesa_hash_table_create(mem_ctx, _mesa_key_hash_string,
_mesa_hash_table_create(mem_ctx, _mesa_hash_string,
_mesa_key_string_equal);
if (block_hash == NULL) {

View File

@@ -2583,13 +2583,13 @@ assign_varying_locations(struct gl_context *ctx,
consumer ? consumer->Stage : MESA_SHADER_NONE);
void *hash_table_ctx = ralloc_context(NULL);
hash_table *tfeedback_candidates =
_mesa_hash_table_create(hash_table_ctx, _mesa_key_hash_string,
_mesa_hash_table_create(hash_table_ctx, _mesa_hash_string,
_mesa_key_string_equal);
hash_table *consumer_inputs =
_mesa_hash_table_create(hash_table_ctx, _mesa_key_hash_string,
_mesa_hash_table_create(hash_table_ctx, _mesa_hash_string,
_mesa_key_string_equal);
hash_table *consumer_interface_inputs =
_mesa_hash_table_create(hash_table_ctx, _mesa_key_hash_string,
_mesa_hash_table_create(hash_table_ctx, _mesa_hash_string,
_mesa_key_string_equal);
ir_variable *consumer_inputs_with_locations[VARYING_SLOT_TESS_MAX] = {
NULL,

View File

@@ -73,7 +73,7 @@ public:
function_list(), added_functions(&function_list, mem_ctx)
{
functions = _mesa_hash_table_create(mem_ctx,
_mesa_key_hash_string,
_mesa_hash_string,
_mesa_key_string_equal);
foreach_in_list(ir_instruction, node, instructions) {

View File

@@ -125,7 +125,7 @@ public:
void
flatten_named_interface_blocks_declarations::run(exec_list *instructions)
{
interface_namespace = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
interface_namespace = _mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
/* First pass: adjust instance block variables with an instance name

View File

@@ -72,7 +72,7 @@ static unsigned
hash_table_var_hash(const void *key)
{
const ir_variable * var = static_cast<const ir_variable *>(key);
return _mesa_key_hash_string(var->name);
return _mesa_hash_string(var->name);
}
output_read_remover::output_read_remover(unsigned stage)

View File

@@ -61,7 +61,7 @@ struct string_to_uint_map {
public:
string_to_uint_map()
{
this->ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
this->ht = _mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
}

View File

@@ -80,11 +80,11 @@ link_varyings::SetUp()
this->ir.make_empty();
this->consumer_inputs =
_mesa_hash_table_create(NULL, _mesa_key_hash_string,
_mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
this->consumer_interface_inputs =
_mesa_hash_table_create(NULL, _mesa_key_hash_string,
_mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
/* Needs to happen after glsl type initialization */

View File

@@ -642,7 +642,7 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns,
if (explicit_matrix_types == NULL) {
explicit_matrix_types =
_mesa_hash_table_create(NULL, _mesa_key_hash_string,
_mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
}
@@ -1007,7 +1007,7 @@ glsl_type::get_array_instance(const glsl_type *base,
assert(glsl_type_users > 0);
if (array_types == NULL) {
array_types = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
array_types = _mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
}

View File

@@ -1486,7 +1486,7 @@ init_print_state(print_state *state, nir_shader *shader, FILE *fp)
state->fp = fp;
state->shader = shader;
state->ht = _mesa_pointer_hash_table_create(NULL);
state->syms = _mesa_set_create(NULL, _mesa_key_hash_string,
state->syms = _mesa_set_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
state->index = 0;
}

View File

@@ -967,7 +967,7 @@ load_oa_metrics(struct gen_perf_config *perf, int fd,
return false;
perf->oa_metrics_table =
_mesa_hash_table_create(perf, _mesa_key_hash_string,
_mesa_hash_table_create(perf, _mesa_hash_string,
_mesa_key_string_equal);
/* Index all the metric sets mesa knows about before looking to see what

View File

@@ -292,7 +292,7 @@ _mesa_symbol_table_ctor(void)
struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
if (table != NULL) {
table->ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
table->ht = _mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
_mesa_symbol_table_push_scope(table);

View File

@@ -555,6 +555,24 @@ _mesa_hash_data(const void *data, size_t size)
return XXH32(data, size, 0);
}
uint32_t
_mesa_hash_int(const void *key)
{
return XXH32(key, sizeof(int), 0);
}
uint32_t
_mesa_hash_uint(const void *key)
{
return XXH32(key, sizeof(unsigned), 0);
}
uint32_t
_mesa_hash_u32(const void *key)
{
return XXH32(key, 4, 0);
}
/** FNV-1a string hash implementation */
uint32_t
_mesa_hash_string(const void *_key)
@@ -570,6 +588,32 @@ _mesa_hash_string(const void *_key)
return hash;
}
uint32_t
_mesa_hash_pointer(const void *pointer)
{
uintptr_t num = (uintptr_t) pointer;
return (uint32_t) ((num >> 2) ^ (num >> 6) ^ (num >> 10) ^ (num >> 14));
}
bool
_mesa_key_int_equal(const void *a, const void *b)
{
return *((const int *)a) == *((const int *)b);
}
bool
_mesa_key_uint_equal(const void *a, const void *b)
{
return *((const unsigned *)a) == *((const unsigned *)b);
}
bool
_mesa_key_u32_equal(const void *a, const void *b)
{
return *((const uint32_t *)a) == *((const uint32_t *)b);
}
/**
* String compare function for use as the comparison callback in
* _mesa_hash_table_create().

View File

@@ -109,21 +109,19 @@ _mesa_hash_table_random_entry(struct hash_table *ht,
bool (*predicate)(struct hash_entry *entry));
uint32_t _mesa_hash_data(const void *data, size_t size);
uint32_t _mesa_hash_int(const void *key);
uint32_t _mesa_hash_uint(const void *key);
uint32_t _mesa_hash_u32(const void *key);
uint32_t _mesa_hash_string(const void *key);
uint32_t _mesa_hash_pointer(const void *pointer);
bool _mesa_key_int_equal(const void *a, const void *b);
bool _mesa_key_uint_equal(const void *a, const void *b);
bool _mesa_key_u32_equal(const void *a, const void *b);
bool _mesa_key_string_equal(const void *a, const void *b);
bool _mesa_key_pointer_equal(const void *a, const void *b);
static inline uint32_t _mesa_key_hash_string(const void *key)
{
return _mesa_hash_string((const char *)key);
}
static inline uint32_t _mesa_hash_pointer(const void *pointer)
{
uintptr_t num = (uintptr_t) pointer;
return (uint32_t) ((num >> 2) ^ (num >> 6) ^ (num >> 10) ^ (num >> 14));
}
struct hash_table *
_mesa_pointer_hash_table_create(void *mem_ctx);

View File

@@ -56,7 +56,7 @@ main(int argc, char **argv)
(void) argc;
(void) argv;
ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
ht = _mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
_mesa_hash_table_insert(ht, str1, NULL);

View File

@@ -43,7 +43,7 @@ main(int argc, char **argv)
(void) argc;
(void) argv;
ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
ht = _mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
_mesa_hash_table_insert(ht, str1, NULL);

View File

@@ -40,7 +40,7 @@ main(int argc, char **argv)
(void) argc;
(void) argv;
ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string, _mesa_key_string_equal);
ht = _mesa_hash_table_create(NULL, _mesa_hash_string, _mesa_key_string_equal);
_mesa_hash_table_insert(ht, str1, NULL);
_mesa_hash_table_insert(ht, str2, NULL);

View File

@@ -45,7 +45,7 @@ main(int argc, char **argv)
assert(str1 != str2);
ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
ht = _mesa_hash_table_create(NULL, _mesa_hash_string,
_mesa_key_string_equal);
_mesa_hash_table_insert(ht, str1, str1);