mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-28 14:40:10 +01:00
util/hash_table: don't allocate the smallest table, declare it in the struct
When compiling Heaven shaders with radeonsi+ACO, this reduces the total number of ralloc calls by 10.8% (same number as the sets, which also reduced it by 10.8%). Apparently we like to create a lot of hash tables. Reviewed-by: Gert Wollny <gert.wollny@collabora.com> Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36728>
This commit is contained in:
parent
2028caad28
commit
bcffade9af
2 changed files with 43 additions and 13 deletions
|
|
@ -167,6 +167,7 @@ _mesa_hash_table_init(struct hash_table *ht,
|
|||
bool (*key_equals_function)(const void *a,
|
||||
const void *b))
|
||||
{
|
||||
ht->mem_ctx = mem_ctx;
|
||||
ht->size_index = 0;
|
||||
ht->size = hash_sizes[ht->size_index].size;
|
||||
ht->rehash = hash_sizes[ht->size_index].rehash;
|
||||
|
|
@ -175,12 +176,14 @@ _mesa_hash_table_init(struct hash_table *ht,
|
|||
ht->max_entries = hash_sizes[ht->size_index].max_entries;
|
||||
ht->key_hash_function = key_hash_function;
|
||||
ht->key_equals_function = key_equals_function;
|
||||
ht->table = rzalloc_array(mem_ctx, struct hash_entry, ht->size);
|
||||
assert(ht->size == ARRAY_SIZE(ht->_initial_storage));
|
||||
ht->table = ht->_initial_storage;
|
||||
memset(ht->table, 0, sizeof(ht->_initial_storage));
|
||||
ht->entries = 0;
|
||||
ht->deleted_entries = 0;
|
||||
ht->deleted_key = &deleted_key_value;
|
||||
|
||||
return ht->table != NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* It's preferred to use _mesa_hash_table_init instead of this to skip ralloc. */
|
||||
|
|
@ -243,16 +246,23 @@ _mesa_hash_table_clone(struct hash_table *src, void *dst_mem_ctx)
|
|||
if (ht == NULL)
|
||||
return NULL;
|
||||
|
||||
memcpy(ht, src, sizeof(struct hash_table));
|
||||
/* Copy the whole structure except the initial storage. */
|
||||
memcpy(ht, src, offsetof(struct hash_table, _initial_storage));
|
||||
ht->mem_ctx = dst_mem_ctx;
|
||||
|
||||
ht->table = ralloc_array(ht, struct hash_entry, ht->size);
|
||||
if (ht->table == NULL) {
|
||||
ralloc_free(ht);
|
||||
return NULL;
|
||||
if (src->table != src->_initial_storage) {
|
||||
ht->table = ralloc_array(dst_mem_ctx, struct hash_entry, ht->size);
|
||||
if (ht->table == NULL) {
|
||||
ralloc_free(ht);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(ht->table, src->table, ht->size * sizeof(struct hash_entry));
|
||||
} else {
|
||||
ht->table = ht->_initial_storage;
|
||||
memcpy(ht->table, src->_initial_storage, sizeof(src->_initial_storage));
|
||||
}
|
||||
|
||||
memcpy(ht->table, src->table, ht->size * sizeof(struct hash_entry));
|
||||
|
||||
return ht;
|
||||
}
|
||||
|
||||
|
|
@ -272,7 +282,9 @@ _mesa_hash_table_fini(struct hash_table *ht,
|
|||
delete_function(entry);
|
||||
}
|
||||
}
|
||||
ralloc_free(ht->table);
|
||||
if (ht->table != ht->_initial_storage)
|
||||
ralloc_free(ht->table);
|
||||
|
||||
ht->table = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -439,12 +451,19 @@ _mesa_hash_table_rehash(struct hash_table *ht, unsigned new_size_index)
|
|||
if (new_size_index >= ARRAY_SIZE(hash_sizes))
|
||||
return;
|
||||
|
||||
table = rzalloc_array(ralloc_parent(ht->table), struct hash_entry,
|
||||
table = rzalloc_array(ht->mem_ctx, struct hash_entry,
|
||||
hash_sizes[new_size_index].size);
|
||||
if (table == NULL)
|
||||
return;
|
||||
|
||||
old_ht = *ht;
|
||||
if (ht->table == ht->_initial_storage) {
|
||||
/* Copy the whole structure including the initial storage. */
|
||||
old_ht = *ht;
|
||||
old_ht.table = old_ht._initial_storage;
|
||||
} else {
|
||||
/* Copy everything except the initial storage. */
|
||||
memcpy(&old_ht, ht, offsetof(struct hash_table, _initial_storage));
|
||||
}
|
||||
|
||||
ht->table = table;
|
||||
ht->size_index = new_size_index;
|
||||
|
|
@ -462,7 +481,8 @@ _mesa_hash_table_rehash(struct hash_table *ht, unsigned new_size_index)
|
|||
|
||||
ht->entries = old_ht.entries;
|
||||
|
||||
ralloc_free(old_ht.table);
|
||||
if (old_ht.table != old_ht._initial_storage)
|
||||
ralloc_free(old_ht.table);
|
||||
}
|
||||
|
||||
static struct hash_entry *
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ struct hash_entry {
|
|||
};
|
||||
|
||||
struct hash_table {
|
||||
void *mem_ctx;
|
||||
struct hash_entry *table;
|
||||
uint32_t (*key_hash_function)(const void *key);
|
||||
bool (*key_equals_function)(const void *a, const void *b);
|
||||
|
|
@ -56,6 +57,15 @@ struct hash_table {
|
|||
uint32_t size_index;
|
||||
uint32_t entries;
|
||||
uint32_t deleted_entries;
|
||||
|
||||
/* "table" points to here at first. A bigger storage is allocated separately
|
||||
* when a bigger size is needed.
|
||||
*/
|
||||
struct hash_entry _initial_storage[19]; /* hash_sizes[0].size */
|
||||
|
||||
/* Don't insert any new fields here. All other fields must be before
|
||||
* _initial_storage.
|
||||
*/
|
||||
};
|
||||
|
||||
struct hash_table *
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue