Skip to content

Commit

Permalink
[benchmarks] Do everything on the heap to avoid stack overflows
Browse files Browse the repository at this point in the history
  • Loading branch information
alexkaratarakis committed Jul 14, 2024
1 parent e32c587 commit 094dc8e
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 28 deletions.
28 changes: 20 additions & 8 deletions test/benchmarks/map_clear.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#include "fixed_containers/fixed_map.hpp"
#include "fixed_containers/fixed_unordered_map.hpp"
#include "fixed_containers/memory.hpp"

#include <benchmark/benchmark.h>

#include <array>
#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <unordered_map>

namespace fixed_containers
Expand All @@ -18,17 +20,20 @@ template <typename MapType>
void benchmark_map_copy(benchmark::State& state)
{
const int64_t nelem = state.range(0);
MapType instance = {};
const std::unique_ptr<MapType> instance_ptr = std::make_unique<MapType>();
MapType& instance = *instance_ptr.get();

using KeyType = typename MapType::key_type;
for (int64_t i = 0; i < nelem; i++)
{
instance.try_emplace(static_cast<KeyType>(i));
}

const std::unique_ptr<MapType> instance_ptr2 = std::make_unique<MapType>();
MapType& instance2 = *instance_ptr2.get();
for (auto _ : state)
{
MapType instance2{instance};
memory::destroy_and_construct_at_address_of(instance2, instance);
benchmark::DoNotOptimize(instance2);
}
}
Expand All @@ -37,16 +42,19 @@ template <typename MapType>
void benchmark_map_copy_then_clear(benchmark::State& state)
{
using KeyType = typename MapType::key_type;
MapType instance{};
const std::unique_ptr<MapType> instance_ptr = std::make_unique<MapType>();
MapType& instance = *instance_ptr.get();
const int64_t nelem = state.range(0);
for (int64_t i = 0; i < nelem; i++)
{
instance.try_emplace(static_cast<KeyType>(i));
}

const std::unique_ptr<MapType> instance_ptr2 = std::make_unique<MapType>();
MapType& instance2 = *instance_ptr2.get();
for (auto _ : state)
{
MapType instance2{instance};
memory::destroy_and_construct_at_address_of(instance2, instance);
instance2.clear();
benchmark::DoNotOptimize(instance2);
}
Expand All @@ -56,25 +64,29 @@ template <typename MapType>
void benchmark_map_copy_then_reconstruct(benchmark::State& state)
{
using KeyType = typename MapType::key_type;
MapType instance{};
const std::unique_ptr<MapType> instance_ptr = std::make_unique<MapType>();
MapType& instance = *instance_ptr.get();
const int64_t nelem = state.range(0);
for (int64_t i = 0; i < nelem; i++)
{
instance.try_emplace(static_cast<KeyType>(i));
}

const std::unique_ptr<MapType> instance_ptr2 = std::make_unique<MapType>();
MapType& instance2 = *instance_ptr2.get();
for (auto _ : state)
{
MapType instance2{instance};
instance2 = {};
memory::destroy_and_construct_at_address_of(instance2, instance);
memory::destroy_and_construct_at_address_of(instance2);
benchmark::DoNotOptimize(instance2);
}
}

template <typename ArrType>
void benchmark_array_clear(benchmark::State& state)
{
ArrType instance{};
const std::unique_ptr<ArrType> instance_ptr = std::make_unique<ArrType>();
ArrType& instance = *instance_ptr.get();

for (auto _ : state)
{
Expand Down
34 changes: 25 additions & 9 deletions test/benchmarks/map_copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

#include "../mock_testing_types.hpp"
#include "fixed_containers/fixed_unordered_map.hpp"
#include "fixed_containers/memory.hpp"

#include <benchmark/benchmark.h>

#include <cstddef>
#include <cstdint>
#include <memory>

namespace fixed_containers
{
Expand All @@ -16,17 +19,20 @@ template <typename MapType>
void benchmark_map_copy_fresh(benchmark::State& state)
{
const int64_t nelem = state.range(0);
MapType instance = {};
const std::unique_ptr<MapType> instance_ptr = std::make_unique<MapType>();
MapType& instance = *instance_ptr.get();

using KeyType = typename MapType::key_type;
for (int64_t i = 0; i < nelem; i++)
{
instance.try_emplace(static_cast<KeyType>(i));
}

const std::unique_ptr<MapType> instance_ptr2 = std::make_unique<MapType>();
MapType& instance2 = *instance_ptr2.get();
for (auto _ : state)
{
MapType instance2{instance};
memory::destroy_and_construct_at_address_of(instance2, instance);
benchmark::DoNotOptimize(instance2);
}
}
Expand All @@ -35,17 +41,19 @@ template <typename MapType>
void benchmark_map_iterate_copy_fresh(benchmark::State& state)
{
const int64_t nelem = state.range(0);
MapType instance = {};
const std::unique_ptr<MapType> instance_ptr = std::make_unique<MapType>();
MapType& instance = *instance_ptr.get();

using KeyType = typename MapType::key_type;
for (int64_t i = 0; i < nelem; i++)
{
instance.try_emplace(static_cast<KeyType>(i));
}

const std::unique_ptr<MapType> instance_ptr2 = std::make_unique<MapType>();
MapType& instance2 = *instance_ptr2.get();
for (auto _ : state)
{
MapType instance2{};
memory::destroy_and_construct_at_address_of(instance2);
for (auto elem : instance)
{
instance2.try_emplace(elem.first, elem.second);
Expand All @@ -58,17 +66,21 @@ template <typename MapType>
void benchmark_map_copy_shuffled(benchmark::State& state)
{
const int64_t nelem = state.range(0);
auto instance = map_benchmarks::make_shuffled_map<MapType>();
const std::unique_ptr<MapType> instance_ptr = std::make_unique<MapType>();
MapType& instance = *instance_ptr.get();
map_benchmarks::make_shuffled_map<MapType>(instance);

using KeyType = typename MapType::key_type;
for (int64_t i = 0; i < nelem; i++)
{
instance.try_emplace(static_cast<KeyType>(i));
}

const std::unique_ptr<MapType> instance_ptr2 = std::make_unique<MapType>();
MapType& instance2 = *instance_ptr2.get();
for (auto _ : state)
{
MapType instance2{instance};
memory::destroy_and_construct_at_address_of(instance2, instance);
benchmark::DoNotOptimize(instance2);
}
}
Expand All @@ -77,17 +89,21 @@ template <typename MapType>
void benchmark_map_iterate_copy_shuffled(benchmark::State& state)
{
const int64_t nelem = state.range(0);
auto instance = map_benchmarks::make_shuffled_map<MapType>();
const std::unique_ptr<MapType> instance_ptr = std::make_unique<MapType>();
MapType& instance = *instance_ptr.get();
map_benchmarks::make_shuffled_map<MapType>(instance);

using KeyType = typename MapType::key_type;
for (int64_t i = 0; i < nelem; i++)
{
instance.try_emplace(static_cast<KeyType>(i));
}

const std::unique_ptr<MapType> instance_ptr2 = std::make_unique<MapType>();
MapType& instance2 = *instance_ptr2.get();
for (auto _ : state)
{
MapType instance2{};
memory::destroy_and_construct_at_address_of(instance2);
for (auto elem : instance)
{
instance2.try_emplace(elem.first, elem.second);
Expand Down
16 changes: 12 additions & 4 deletions test/benchmarks/map_lookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

#include <benchmark/benchmark.h>

#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <unordered_map>

namespace fixed_containers
Expand All @@ -17,7 +19,8 @@ template <typename MapType>
void benchmark_map_lookup_fresh(benchmark::State& state)
{
using KeyType = typename MapType::key_type;
MapType instance{};
const std::unique_ptr<MapType> instance_ptr = std::make_unique<MapType>();
MapType& instance = *instance_ptr.get();
const int64_t nelem = state.range(0);
for (int64_t i = 0; i < nelem; i++)
{
Expand All @@ -38,7 +41,9 @@ template <typename MapType>
void benchmark_map_lookup_shuffled(benchmark::State& state)
{
using KeyType = typename MapType::key_type;
auto instance = map_benchmarks::make_shuffled_map<MapType>();
const std::unique_ptr<MapType> instance_ptr = std::make_unique<MapType>();
MapType& instance = *instance_ptr.get();
map_benchmarks::make_shuffled_map<MapType>(instance);
const int64_t nelem = state.range(0);
for (int64_t i = 0; i < nelem; i++)
{
Expand All @@ -59,7 +64,8 @@ template <typename MapType>
void benchmark_map_iterate_fresh(benchmark::State& state)
{
using KeyType = typename MapType::key_type;
MapType instance{};
const std::unique_ptr<MapType> instance_ptr = std::make_unique<MapType>();
MapType& instance = *instance_ptr.get();
const int64_t nelem = state.range(0);
for (int64_t i = 0; i < nelem; i++)
{
Expand All @@ -79,7 +85,9 @@ template <typename MapType>
void benchmark_map_iterate_shuffled(benchmark::State& state)
{
using KeyType = typename MapType::key_type;
auto instance = map_benchmarks::make_shuffled_map<MapType>();
const std::unique_ptr<MapType> instance_ptr = std::make_unique<MapType>();
MapType& instance = *instance_ptr.get();
map_benchmarks::make_shuffled_map<MapType>(instance);
const int64_t nelem = state.range(0);
for (int64_t i = 0; i < nelem; i++)
{
Expand Down
12 changes: 5 additions & 7 deletions test/benchmarks/map_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace fixed_containers::map_benchmarks
{

template <typename MapType>
[[maybe_unused]] static void del(MapType& map, int64_t divisor)
constexpr void del(MapType& map, int64_t divisor)
{
auto iter = map.begin();
while (iter != map.end())
Expand All @@ -24,7 +24,7 @@ template <typename MapType>
}

template <typename MapType>
[[maybe_unused]] static void replace_low(MapType& map, std::size_t divisor)
constexpr void replace_low(MapType& map, std::size_t divisor)
{
using KeyType = typename MapType::key_type;
for (std::size_t i = 0; i < map.max_size(); i += divisor)
Expand All @@ -34,7 +34,7 @@ template <typename MapType>
}

template <typename MapType>
[[maybe_unused]] static void replace_high(MapType& map, std::size_t divisor)
constexpr void replace_high(MapType& map, std::size_t divisor)
{
using KeyType = typename MapType::key_type;
// find the largest multiple smaller than `n`
Expand All @@ -49,10 +49,10 @@ template <typename MapType>
// create a "well-used" map, so that new elements will be inserted into dispersed spots in the map
// instead of spots with good memory locality
template <typename MapType>
[[maybe_unused]] static MapType make_shuffled_map()
constexpr void make_shuffled_map(MapType& instance)
{
using KeyType = typename MapType::key_type;
MapType instance{};
instance.clear();
// fill the map completely
for (std::size_t i = 0; i < instance.max_size(); i++)
{
Expand Down Expand Up @@ -83,8 +83,6 @@ template <typename MapType>
del(instance, 1023);
del(instance, 15);
del(instance, 1);

return instance;
}

} // namespace fixed_containers::map_benchmarks

0 comments on commit 094dc8e

Please sign in to comment.