Add hashtable benchmark coverage for integers with low zero bits (#5735)

These have unique challenges for our hashing scheme, and so its useful
to make sure the hash functions we use can handle them.

Some other work on Abseil's hash tables uncovered that this might be
risky and may have surfaced some improvements to reduce the impact here,
but the first step seems to try and start covering this path in the
benchmarks.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Chandler Carruth
2025-06-28 00:52:58 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent 4aa62bf5cd
commit b39c7c93aa
4 changed files with 130 additions and 0 deletions
+17
View File
@@ -19,6 +19,7 @@ using RawHashtable::CarbonHashDI;
using RawHashtable::GetKeysAndHitKeys;
using RawHashtable::GetKeysAndMissKeys;
using RawHashtable::HitArgs;
using RawHashtable::LowZeroBitInt;
using RawHashtable::ReportTableMetrics;
using RawHashtable::SizeArgs;
using RawHashtable::ValueToBool;
@@ -328,6 +329,22 @@ static void BM_MapLookupHit(benchmark::State& state) {
}
MAP_BENCHMARK_ONE_OP(BM_MapLookupHit, HitArgs);
// We also do some minimal benchmarking with integers that have a
// large number of low zero bits shifted into them. These present particular
// challenges to the hashing strategy Carbon's hash tables use and so they help
// form stress tests and benchmark to make sure the hash function quality
// remains reasonable even under adverse conditions. We can't go past a certain
// limit here without our hash tables becoming impossibly slow due to complete
// collapse of the hash functions -- if we ever need to hash integers with more
// than 32 low zero bits, we'll ask that code to use a custom hash algorithm.
//
// We don't benchmark these everywhere as they only provide marginal information
// beyond the core types, and checking just this operation covers that
// sufficiently.
MAP_BENCHMARK_ONE_OP_SIZE(BM_MapLookupHit, HitArgs, LowZeroBitInt<12>, int);
MAP_BENCHMARK_ONE_OP_SIZE(BM_MapLookupHit, HitArgs, LowZeroBitInt<24>, int);
MAP_BENCHMARK_ONE_OP_SIZE(BM_MapLookupHit, HitArgs, LowZeroBitInt<32>, int);
// This is an update throughput benchmark in practice. While whether the key was
// a hit is kept in the critical path, we only use keys that are hits and so
// expect that to be fully predicted and speculated.