This gives better performance as we can do bitmasking
instead of modulo operations.

This reduces oprofile hits on a shader-db run accordingly:
hash_table_insert       4.28 ---> 2.57
hash_table_search       4.59 ---> 2.67
runtime                 175  ---> 170

Since the last patch hits assertion failures this is
the result for these two patches combined.
---
 src/util/hash_table.c | 75 ++++++++++++++++++++++++++-------------------------
 1 file changed, 38 insertions(+), 37 deletions(-)

diff --git a/src/util/hash_table.c b/src/util/hash_table.c
index 542f583..49a1fea 100644
--- a/src/util/hash_table.c
+++ b/src/util/hash_table.c
@@ -51,44 +51,45 @@
 static const uint32_t deleted_key_value;
 
 /**
- * From Knuth -- a good choice for hash values is p, where is prime.
+ * We chose table sizes that's a power of two.
+ * This is computationally less expensive than primes.
+ * FNV-1a has good avalanche properties, so collision is not an issue.
  * These tables are sized to have an extra 10% free to avoid
  * exponential performance degradation as the hash table fills
  */
 static const struct {
    uint32_t max_entries, size;
 } hash_sizes[] = {
-   { 2,                        5               },
-   { 4,                        7               },
-   { 8,                        13              },
-   { 16,               19              },
-   { 32,               43              },
-   { 64,               73              },
-   { 128,              151             },
-   { 256,              283             },
-   { 512,              571             },
-   { 1024,             1153            },
-   { 2048,             2269            },
-   { 4096,             4519            },
-   { 8192,             9013            },
-   { 16384,            18043           },
-   { 32768,            36109           },
-   { 65536,            72091           },
-   { 131072,           144409          },
-   { 262144,           288361          },
-   { 524288,           576883          },
-   { 1048576,          1153459 },
-   { 2097152,          2307163 },
-   { 4194304,          4613893 },
-   { 8388608,          9227641 },
-   { 16777216,         18455029        },
-   { 33554432,         36911011        },
-   { 67108864,         73819861        },
-   { 134217728,                147639589       },
-   { 268435456,                295279081       },
-   { 536870912,                590559793       },
-   { 1073741824,       1181116273      },
-   { 2147483648ul,     2362232233ul}
+      { 3,            4            },
+      { 7,            8            },
+      { 14,           16           },
+      { 28,           32           },
+      { 57,           64           },
+      { 115,          128          },
+      { 230,          256          },
+      { 460,          512          },
+      { 921,          1024         },
+      { 1843,         2048         },
+      { 3686,         4096         },
+      { 7372,         8192         },
+      { 14745,        16384        },
+      { 29491,        32768        },
+      { 58982,        65536        },
+      { 117964,       131072       },
+      { 235929,       262144       },
+      { 471859,       524288       },
+      { 943718,       1048576      },
+      { 1887436,      2097152      },
+      { 3774873,      4194304      },
+      { 7549747,      8388608      },
+      { 15099494,     16777216     },
+      { 30198988,     33554432     },
+      { 60397977,     67108864     },
+      { 120795955,    134217728    },
+      { 241591910,    268435456    },
+      { 483183820,    536870912    },
+      { 966367641,    1073741824   },
+      { 1932735283ul, 2147483648ul }
 };
 
 static int
@@ -181,7 +182,7 @@ _mesa_hash_table_set_deleted_key(struct hash_table *ht, 
const void *deleted_key)
 static struct hash_entry *
 hash_table_search(struct hash_table *ht, uint32_t hash, const void *key)
 {
-   uint32_t start_hash_address = hash % ht->size;
+   uint32_t start_hash_address = hash & (ht->size -1);
    uint32_t hash_address = start_hash_address;
    uint32_t quad_hash = 1;
 
@@ -196,7 +197,7 @@ hash_table_search(struct hash_table *ht, uint32_t hash, 
const void *key)
          }
       }
 
-      hash_address = (hash_address + quad_hash*quad_hash) % ht->size;
+      hash_address = (hash_address + quad_hash*quad_hash) & (ht->size -1);
       quad_hash++;
    } while (hash_address != start_hash_address);
 
@@ -272,7 +273,7 @@ hash_table_insert(struct hash_table *ht, uint32_t hash,
       _mesa_hash_table_rehash(ht, ht->size_index);
    }
 
-   start_hash_address = hash % ht->size;
+   start_hash_address = hash & (ht->size -1);
    hash_address = start_hash_address;
 
    do {
@@ -304,7 +305,7 @@ hash_table_insert(struct hash_table *ht, uint32_t hash,
          return entry;
       }
 
-      hash_address = (hash_address + quad_hash*quad_hash) % ht->size;
+      hash_address = (hash_address + quad_hash*quad_hash) & (ht->size -1);
       quad_hash++;
    } while (hash_address != start_hash_address);
 
@@ -400,7 +401,7 @@ _mesa_hash_table_random_entry(struct hash_table *ht,
                               bool (*predicate)(struct hash_entry *entry))
 {
    struct hash_entry *entry;
-   uint32_t i = rand() % ht->size;
+   uint32_t i = rand() & (ht->size -1);
 
    if (ht->entries == 0)
       return NULL;
-- 
2.2.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to