Skip to content

Commit

Permalink
Make the cwisstable_benchmark workload match Abseil exactly
Browse files Browse the repository at this point in the history
  • Loading branch information
mcy committed Feb 7, 2022
1 parent 44e4f8d commit 99847ba
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 15 deletions.
49 changes: 34 additions & 15 deletions cwisstable/cwisstable_benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ namespace {

using benchmark::DoNotOptimize;

CWISS_DECLARE_HASHSET_WITH(StringTable, std::string,
(FlatPolicy<std::string, HashStdString>()));
CWISS_DECLARE_HASHMAP_WITH(
StringTable, std::string, std::string,
(FlatMapPolicy<std::string, std::string, HashStdString>()));
CWISS_DECLARE_HASHSET_WITH(IntTable, int64_t, FlatPolicy<int64_t>());

TABLE_HELPERS(StringTable);
TABLE_HELPERS(IntTable);

struct StringGen {
Expand Down Expand Up @@ -62,9 +62,14 @@ void BM_CacheInSteadyState(benchmark::State& state) {

std::deque<std::string> keys;
while (StringTable_size(&t) < state.range(0)) {
auto [val, inserted] = MoveInsert(t, gen(rng));
std::string k = gen(rng);
std::string v = gen(rng);
auto [it, inserted] = StringTable_deferred_insert(&t, &k);
if (inserted) {
keys.push_back(*val);
auto* ptr = StringTable_Iter_get(&it);
new (&ptr->key) std::string(std::move(k));
new (&ptr->val) std::string(std::move(v));
keys.push_back(ptr->key);
}
}

Expand All @@ -77,21 +82,28 @@ void BM_CacheInSteadyState(benchmark::State& state) {
it = keys.end();
}

DoNotOptimize(Find(t, *--it));
DoNotOptimize(StringTable_find(&t, &*--it));
}

// Some cache misses.
for (int i = 0; i != 10; ++i) {
DoNotOptimize(Find(t, gen(rng)));
std::string s = gen(rng);
DoNotOptimize(StringTable_find(&t, &s));
}

CWISS_CHECK(Erase(t, keys.front()), "missing? %s", keys.front().c_str());
CWISS_CHECK(StringTable_erase(&t, &keys.front()), "missing? %s",
keys.front().c_str());

keys.pop_front();
while (true) {
auto [val, inserted] = MoveInsert(t, gen(rng));
std::string k = gen(rng);
std::string v = gen(rng);
auto [it, inserted] = StringTable_deferred_insert(&t, &k);
if (inserted) {
keys.push_back(*val);
auto* ptr = StringTable_Iter_get(&it);
new (&ptr->key) std::string(std::move(k));
new (&ptr->val) std::string(std::move(v));
keys.push_back(ptr->key);
break;
}
}
Expand Down Expand Up @@ -119,6 +131,9 @@ void CacheInSteadyStateArgs(Benchmark* bm) {
}
BENCHMARK(BM_CacheInSteadyState)->Apply(CacheInSteadyStateArgs);

// This is miscompiled by GCC, so the benchmark will be messed up on that
// compiler.
#if !CWISS_IS_GCC
void BM_EndComparison(benchmark::State& state) {
std::random_device rd;
std::mt19937 rng(rd());
Expand All @@ -127,23 +142,27 @@ void BM_EndComparison(benchmark::State& state) {
absl::Cleanup c_ = [&] { StringTable_destroy(&t); };

while (StringTable_size(&t) < state.range(0)) {
MoveInsert(t, gen(rng));
std::string k = gen(rng);
std::string v = gen(rng);
auto [it, inserted] = StringTable_deferred_insert(&t, &k);
if (inserted) {
auto* ptr = StringTable_Iter_get(&it);
new (&ptr->key) std::string(std::move(k));
new (&ptr->val) std::string(std::move(v));
}
}

for (auto ignored : state) {
for (auto it = StringTable_iter(&t); StringTable_Iter_get(&it);
StringTable_Iter_next(&it)) {
// This is miscompiled by GCC, so the benchmark will be messed up on that
// compiler.
#if CWISS_IS_GCC
DoNotOptimize(it);
#endif
DoNotOptimize(t);
DoNotOptimize(StringTable_Iter_get(&it) != NULL);
}
}
}
BENCHMARK(BM_EndComparison)->Arg(400);
#endif

void BM_CopyCtor(benchmark::State& state) {
std::random_device rd;
Expand Down
35 changes: 35 additions & 0 deletions cwisstable/internal/test_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,41 @@ constexpr const CWISS_Policy& FlatPolicy() {
return FlatPolicyWrapper<T, Hash, Eq>::kPolicy;
}

template <typename K, typename V, typename Hash, typename Eq>
struct FlatMapPolicyWrapper {
CWISS_GCC_PUSH_
CWISS_GCC_ALLOW_("-Waddress")
// clang-format off
CWISS_DECLARE_FLAT_MAP_POLICY(kPolicy, K, V,
(modifiers, static constexpr),
(obj_copy, [](void* dst, const void* src) {
new (dst) kPolicy_Entry(*static_cast<const kPolicy_Entry*>(src));
}),
(obj_dtor, [](void* val) {
static_cast<kPolicy_Entry*>(val)->~kPolicy_Entry();
}),
(key_hash, [](const void* val) {
return Hash{}(static_cast<const kPolicy_Entry*>(val)->k);
}),
(key_eq, [](const void* a, const void* b) {
return Eq{}(static_cast<const kPolicy_Entry*>(a)->k,
static_cast<const kPolicy_Entry*>(b)->k);
}),
(slot_transfer, [](void* dst, void* src) {
kPolicy_Entry* old = static_cast<kPolicy_Entry*>(src);
new (dst) kPolicy_Entry(std::move(*old));
old->~kPolicy_Entry();
}));
// clang-format on
CWISS_GCC_POP_
};

template <typename K, typename V, typename Hash = DefaultHash<K>,
typename Eq = DefaultEq<K>>
constexpr const CWISS_Policy& FlatMapPolicy() {
return FlatMapPolicyWrapper<K, V, Hash, Eq>::kPolicy;
}

// Helpers for doing some operations on tables with minimal pain.
//
// This macro expands to functions that will form an overload set with other
Expand Down

0 comments on commit 99847ba

Please sign in to comment.