mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 07:11:04 +01:00
Collect more detailed metrics on hashtables. (#4046)
Previously we just looked at the raw count of probed keys. Now, we compute the average and max of both the probe _distance_ measured in the number of _groups_ probed, and the number of probe _compares_ measured in the compares required _before_ finding the matching entry. This lets us understand the relative impact of probe-distance vs. tag collisions on a given set of benchmark keys. Some of this is motivated by considering additional optimization techniques similar to those used in Boost's table and the F14 table from Facebook/Meta. --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
21a81bc59e
commit
3be57b71e0
@@ -18,6 +18,7 @@ using RawHashtable::CarbonHashDI;
|
||||
using RawHashtable::GetKeysAndHitKeys;
|
||||
using RawHashtable::GetKeysAndMissKeys;
|
||||
using RawHashtable::HitArgs;
|
||||
using RawHashtable::ReportTableMetrics;
|
||||
using RawHashtable::SizeArgs;
|
||||
using RawHashtable::ValueToBool;
|
||||
|
||||
@@ -159,6 +160,15 @@ template <typename MapT>
|
||||
using MapWrapper =
|
||||
MapWrapperOverride<MapT, MapOverride::CARBON_MAP_BENCH_OVERRIDE>;
|
||||
|
||||
template <typename MapT>
|
||||
auto ReportMetrics(const MapWrapper<MapT>& m_wrapper, benchmark::State& state)
|
||||
-> void {
|
||||
// Report some extra statistics about the Carbon type.
|
||||
if constexpr (IsCarbonMap<MapT>) {
|
||||
ReportTableMetrics(m_wrapper.m, state);
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTBEGIN(bugprone-macro-parentheses): Parentheses are incorrect here.
|
||||
#define MAP_BENCHMARK_ONE_OP_SIZE(NAME, APPLY, KT, VT) \
|
||||
BENCHMARK(NAME<Map<KT, VT>>)->Apply(APPLY); \
|
||||
@@ -223,6 +233,8 @@ static void BM_MapContainsHit(benchmark::State& state) {
|
||||
i += static_cast<ssize_t>(result);
|
||||
}
|
||||
}
|
||||
|
||||
ReportMetrics(m, state);
|
||||
}
|
||||
MAP_BENCHMARK_ONE_OP(BM_MapContainsHit, HitArgs);
|
||||
|
||||
@@ -250,6 +262,8 @@ static void BM_MapContainsMiss(benchmark::State& state) {
|
||||
i += static_cast<ssize_t>(!result);
|
||||
}
|
||||
}
|
||||
|
||||
ReportMetrics(m, state);
|
||||
}
|
||||
MAP_BENCHMARK_ONE_OP(BM_MapContainsMiss, SizeArgs);
|
||||
|
||||
@@ -302,6 +316,8 @@ static void BM_MapLookupHit(benchmark::State& state) {
|
||||
i += static_cast<ssize_t>(result);
|
||||
}
|
||||
}
|
||||
|
||||
ReportMetrics(m, state);
|
||||
}
|
||||
MAP_BENCHMARK_ONE_OP(BM_MapLookupHit, HitArgs);
|
||||
|
||||
@@ -339,6 +355,8 @@ static void BM_MapUpdateHit(benchmark::State& state) {
|
||||
CARBON_DCHECK(!inserted);
|
||||
}
|
||||
}
|
||||
|
||||
ReportMetrics(m, state);
|
||||
}
|
||||
MAP_BENCHMARK_ONE_OP(BM_MapUpdateHit, HitArgs);
|
||||
|
||||
@@ -454,19 +472,13 @@ static void BM_MapInsertSeq(benchmark::State& state) {
|
||||
if constexpr (IsCarbonMap<MapT>) {
|
||||
// Re-build a map outside of the timing loop to look at the statistics
|
||||
// rather than the timing.
|
||||
MapT m;
|
||||
MapWrapperT m;
|
||||
for (auto k : keys) {
|
||||
bool inserted = m.Insert(k, MakeValue<VT>()).is_inserted();
|
||||
bool inserted = m.BenchInsert(k, MakeValue<VT>());
|
||||
CARBON_DCHECK(inserted) << "Must be a successful insert!";
|
||||
}
|
||||
|
||||
// While this count is "iteration invariant" (it should be exactly the same
|
||||
// for every iteration as the set of keys is the same), we don't use that
|
||||
// because it will scale this by the number of iterations. We want to
|
||||
// display the probe count of this benchmark *parameter*, not the probe
|
||||
// count that resulted from the number of iterations. That means we use the
|
||||
// normal counter API without flags.
|
||||
state.counters["Probed"] = m.CountProbedKeys();
|
||||
ReportMetrics(m, state);
|
||||
|
||||
// Uncomment this call to print out statistics about the index-collisions
|
||||
// among these keys for debugging:
|
||||
|
||||
Reference in New Issue
Block a user