Skip to content

Commit 13d419b

Browse files
committed
[benchmark] Add traditional inheritance to benchmarks
1 parent f7f3cb4 commit 13d419b

11 files changed

+135
-45
lines changed

Diff for: benchmark/storage/ctor.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ static void BM_ctor(benchmark::State& state) {
2929
template <std::size_t Bytes>
3030
using WithSize = std::aligned_storage_t<Bytes>;
3131

32+
BENCHMARK_TEMPLATE(BM_ctor, inheritance_tag, WithSize<4>);
3233
BENCHMARK_TEMPLATE(BM_ctor, dyno::remote_storage, WithSize<4>);
3334
BENCHMARK_TEMPLATE(BM_ctor, dyno::sbo_storage<4>, WithSize<4>);
3435
BENCHMARK_TEMPLATE(BM_ctor, dyno::sbo_storage<8>, WithSize<4>);
3536
BENCHMARK_TEMPLATE(BM_ctor, dyno::sbo_storage<16>, WithSize<4>);
3637
BENCHMARK_TEMPLATE(BM_ctor, dyno::local_storage<16>, WithSize<4>);
3738

39+
BENCHMARK_TEMPLATE(BM_ctor, inheritance_tag, WithSize<16>);
3840
BENCHMARK_TEMPLATE(BM_ctor, dyno::remote_storage, WithSize<16>);
3941
BENCHMARK_TEMPLATE(BM_ctor, dyno::sbo_storage<4>, WithSize<16>);
4042
BENCHMARK_TEMPLATE(BM_ctor, dyno::sbo_storage<8>, WithSize<16>);

Diff for: benchmark/storage/ctor.move.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ static void BM_move(benchmark::State& state) {
3030
template <std::size_t Bytes>
3131
using WithSize = std::aligned_storage_t<Bytes>;
3232

33+
BENCHMARK_TEMPLATE(BM_move, inheritance_tag, WithSize<4>);
3334
BENCHMARK_TEMPLATE(BM_move, dyno::remote_storage, WithSize<4>);
3435
BENCHMARK_TEMPLATE(BM_move, dyno::sbo_storage<4>, WithSize<4>);
3536
BENCHMARK_TEMPLATE(BM_move, dyno::sbo_storage<8>, WithSize<4>);
3637
BENCHMARK_TEMPLATE(BM_move, dyno::sbo_storage<16>, WithSize<4>);
3738
BENCHMARK_TEMPLATE(BM_move, dyno::local_storage<16>, WithSize<4>);
3839

40+
BENCHMARK_TEMPLATE(BM_move, inheritance_tag, WithSize<16>);
3941
BENCHMARK_TEMPLATE(BM_move, dyno::remote_storage, WithSize<16>);
4042
BENCHMARK_TEMPLATE(BM_move, dyno::sbo_storage<4>, WithSize<16>);
4143
BENCHMARK_TEMPLATE(BM_move, dyno::sbo_storage<8>, WithSize<16>);

Diff for: benchmark/storage/dispatch.many.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ static void BM_dispatch_many(benchmark::State& state) {
3030
benchmark::DoNotOptimize(models);
3131
while (state.KeepRunning()) {
3232
for (auto& model : models) {
33-
model.a();
34-
model.b();
35-
model.c();
33+
model.f1();
34+
model.f2();
35+
model.f3();
3636
}
3737
}
3838
}
@@ -44,6 +44,7 @@ static constexpr int N = 10;
4444

4545
// Always insert the same type in the type-erasure wrapper (may interact with
4646
// branch prediction and caches).
47+
BENCHMARK_TEMPLATE(BM_dispatch_many, inheritance_tag, WithSize<4>, WithSize<4>)->Arg(N);
4748
BENCHMARK_TEMPLATE(BM_dispatch_many, dyno::remote_storage, WithSize<4>, WithSize<4>)->Arg(N);
4849
BENCHMARK_TEMPLATE(BM_dispatch_many, dyno::sbo_storage<4>, WithSize<4>, WithSize<4>)->Arg(N);
4950
BENCHMARK_TEMPLATE(BM_dispatch_many, dyno::sbo_storage<8>, WithSize<4>, WithSize<4>)->Arg(N);
@@ -56,6 +57,7 @@ BENCHMARK_TEMPLATE(BM_dispatch_many, dyno::local_storage<16>, WithSize<8>, WithS
5657

5758
// Insert two different types in the type-erasure wrapper to look at what happens
5859
// with SBO.
60+
BENCHMARK_TEMPLATE(BM_dispatch_many, inheritance_tag, WithSize<8>, WithSize<16>)->Arg(N);
5961
BENCHMARK_TEMPLATE(BM_dispatch_many, dyno::remote_storage, WithSize<8>, WithSize<16>)->Arg(N);
6062
BENCHMARK_TEMPLATE(BM_dispatch_many, dyno::sbo_storage<4>, WithSize<8>, WithSize<16>)->Arg(N);
6163
BENCHMARK_TEMPLATE(BM_dispatch_many, dyno::sbo_storage<8>, WithSize<8>, WithSize<16>)->Arg(N);

Diff for: benchmark/storage/dispatch.single.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@ static void BM_dispatch_single(benchmark::State& state) {
2121
model<StoragePolicy> m{T{}};
2222
benchmark::DoNotOptimize(m);
2323
while (state.KeepRunning()) {
24-
m.a();
25-
m.b();
26-
m.c();
24+
m.f1();
25+
m.f2();
26+
m.f3();
2727
}
2828
}
2929

3030
template <std::size_t Bytes>
3131
using WithSize = std::aligned_storage_t<Bytes>;
3232

33+
BENCHMARK_TEMPLATE(BM_dispatch_single, inheritance_tag, WithSize<8>);
3334
BENCHMARK_TEMPLATE(BM_dispatch_single, dyno::remote_storage, WithSize<8>);
3435
BENCHMARK_TEMPLATE(BM_dispatch_single, dyno::sbo_storage<4>, WithSize<8>);
3536
BENCHMARK_TEMPLATE(BM_dispatch_single, dyno::sbo_storage<8>, WithSize<8>);

Diff for: benchmark/storage/model.hpp

+44-9
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ struct Concept : decltype(dyno::requires(
1616
dyno::Swappable{},
1717
dyno::Destructible{},
1818
dyno::Storable{},
19-
"a"_s = dyno::function<void(dyno::T&)>,
20-
"b"_s = dyno::function<void(dyno::T&)>,
21-
"c"_s = dyno::function<void(dyno::T&)>
19+
"f1"_s = dyno::function<void(dyno::T&)>,
20+
"f2"_s = dyno::function<void(dyno::T&)>,
21+
"f3"_s = dyno::function<void(dyno::T&)>
2222
)) { };
2323

2424
template <typename T>
2525
auto const dyno::default_concept_map<Concept, T> = dyno::make_concept_map(
26-
"a"_s = [](T& self) { benchmark::DoNotOptimize(self); },
27-
"b"_s = [](T& self) { benchmark::DoNotOptimize(self); },
28-
"c"_s = [](T& self) { benchmark::DoNotOptimize(self); }
26+
"f1"_s = [](T& self) { benchmark::DoNotOptimize(self); },
27+
"f2"_s = [](T& self) { benchmark::DoNotOptimize(self); },
28+
"f3"_s = [](T& self) { benchmark::DoNotOptimize(self); }
2929
);
3030

3131
template <typename StoragePolicy>
@@ -37,12 +37,47 @@ struct model {
3737

3838
void swap(model& other) { poly_.swap(other.poly_); }
3939

40-
void a() { poly_.virtual_("a"_s)(poly_); }
41-
void b() { poly_.virtual_("b"_s)(poly_); }
42-
void c() { poly_.virtual_("c"_s)(poly_); }
40+
void f1() { poly_.virtual_("f1"_s)(poly_); }
41+
void f2() { poly_.virtual_("f2"_s)(poly_); }
42+
void f3() { poly_.virtual_("f3"_s)(poly_); }
4343

4444
private:
4545
dyno::poly<Concept, StoragePolicy> poly_;
4646
};
4747

48+
struct inheritance_tag { };
49+
50+
template <>
51+
struct model<inheritance_tag> {
52+
template <typename T>
53+
explicit model(T t)
54+
: self_{std::make_unique<model_t<T>>(std::move(t))}
55+
{ }
56+
57+
void swap(model& other) { std::swap(self_, other.self_); }
58+
59+
void f1() { self_->f1(); }
60+
void f2() { self_->f2(); }
61+
void f3() { self_->f3(); }
62+
63+
private:
64+
struct concept_t {
65+
virtual void f1() = 0;
66+
virtual void f2() = 0;
67+
virtual void f3() = 0;
68+
virtual ~concept_t() { }
69+
};
70+
71+
template <typename T>
72+
struct model_t : concept_t {
73+
model_t(T v) : value_{std::move(v)} { }
74+
void f1() override { benchmark::DoNotOptimize(value_); }
75+
void f2() override { benchmark::DoNotOptimize(value_); }
76+
void f3() override { benchmark::DoNotOptimize(value_); }
77+
T value_;
78+
};
79+
80+
std::unique_ptr<concept_t> self_;
81+
};
82+
4883
#endif // BENCHMARK_STORAGE_MODEL_HPP

Diff for: benchmark/storage/swap.different.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ static void BM_swap_different(benchmark::State& state) {
2828
}
2929
}
3030

31+
BENCHMARK_TEMPLATE(BM_swap_different, inheritance_tag);
3132
BENCHMARK_TEMPLATE(BM_swap_different, dyno::sbo_storage<4>);
3233
BENCHMARK_TEMPLATE(BM_swap_different, dyno::sbo_storage<8>);
3334
BENCHMARK_TEMPLATE(BM_swap_different, dyno::sbo_storage<16>);

Diff for: benchmark/storage/swap.same.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ static void BM_swap_same(benchmark::State& state) {
2828
}
2929
}
3030

31+
BENCHMARK_TEMPLATE(BM_swap_same, inheritance_tag);
3132
BENCHMARK_TEMPLATE(BM_swap_same, dyno::sbo_storage<4>);
3233
BENCHMARK_TEMPLATE(BM_swap_same, dyno::sbo_storage<8>);
3334
BENCHMARK_TEMPLATE(BM_swap_same, dyno::sbo_storage<16>);

Diff for: benchmark/vtable/dispatch.2.cpp

+12-9
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,10 @@ using namespace dyno::literals;
1111

1212

1313
// This benchmark measures the overhead of dispatching virtual calls using
14-
// different vtable policies.
14+
// different vtable policies, and inheritance.
1515

16-
template <typename ...InlineMethods>
16+
template <typename VTablePolicy>
1717
static void BM_dispatch2(benchmark::State& state) {
18-
using VTablePolicy = dyno::vtable<
19-
dyno::local<dyno::only<InlineMethods...>>,
20-
dyno::remote<dyno::everything_else>
21-
>;
2218
unsigned int x = 0;
2319
model<VTablePolicy> m{x};
2420
int const N = state.range(0);
@@ -31,8 +27,15 @@ static void BM_dispatch2(benchmark::State& state) {
3127
}
3228
}
3329

30+
template <typename ...InlineMethods>
31+
using inline_only = dyno::vtable<
32+
dyno::local<dyno::only<InlineMethods...>>,
33+
dyno::remote<dyno::everything_else>
34+
>;
35+
3436
static constexpr int N = 100;
35-
BENCHMARK(BM_dispatch2)->Arg(N);
36-
BENCHMARK_TEMPLATE(BM_dispatch2, decltype("f1"_s))->Arg(N);
37-
BENCHMARK_TEMPLATE(BM_dispatch2, decltype("f1"_s), decltype("f2"_s))->Arg(N);
37+
BENCHMARK_TEMPLATE(BM_dispatch2, inheritance_tag)->Arg(N);
38+
BENCHMARK_TEMPLATE(BM_dispatch2, inline_only<>)->Arg(N);
39+
BENCHMARK_TEMPLATE(BM_dispatch2, inline_only<decltype("f1"_s)>)->Arg(N);
40+
BENCHMARK_TEMPLATE(BM_dispatch2, inline_only<decltype("f1"_s), decltype("f2"_s)>)->Arg(N);
3841
BENCHMARK_MAIN();

Diff for: benchmark/vtable/dispatch.3.cpp

+13-10
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,10 @@ using namespace dyno::literals;
1111

1212

1313
// This benchmark measures the overhead of dispatching virtual calls using
14-
// different vtable policies.
14+
// different vtable policies, and inheritance.
1515

16-
template <typename ...InlineMethods>
16+
template <typename VTablePolicy>
1717
static void BM_dispatch3(benchmark::State& state) {
18-
using VTablePolicy = dyno::vtable<
19-
dyno::local<dyno::only<InlineMethods...>>,
20-
dyno::remote<dyno::everything_else>
21-
>;
2218
unsigned int x = 0;
2319
model<VTablePolicy> m{x};
2420
int const N = state.range(0);
@@ -32,9 +28,16 @@ static void BM_dispatch3(benchmark::State& state) {
3228
}
3329
}
3430

31+
template <typename ...InlineMethods>
32+
using inline_only = dyno::vtable<
33+
dyno::local<dyno::only<InlineMethods...>>,
34+
dyno::remote<dyno::everything_else>
35+
>;
36+
3537
static constexpr int N = 100;
36-
BENCHMARK(BM_dispatch3)->Arg(N);
37-
BENCHMARK_TEMPLATE(BM_dispatch3, decltype("f1"_s))->Arg(N);
38-
BENCHMARK_TEMPLATE(BM_dispatch3, decltype("f1"_s), decltype("f2"_s))->Arg(N);
39-
BENCHMARK_TEMPLATE(BM_dispatch3, decltype("f1"_s), decltype("f2"_s), decltype("f3"_s))->Arg(N);
38+
BENCHMARK_TEMPLATE(BM_dispatch3, inheritance_tag)->Arg(N);
39+
BENCHMARK_TEMPLATE(BM_dispatch3, inline_only<>)->Arg(N);
40+
BENCHMARK_TEMPLATE(BM_dispatch3, inline_only<decltype("f1"_s)>)->Arg(N);
41+
BENCHMARK_TEMPLATE(BM_dispatch3, inline_only<decltype("f1"_s), decltype("f2"_s)>)->Arg(N);
42+
BENCHMARK_TEMPLATE(BM_dispatch3, inline_only<decltype("f1"_s), decltype("f2"_s), decltype("f3"_s)>)->Arg(N);
4043
BENCHMARK_MAIN();

Diff for: benchmark/vtable/dispatch.4.cpp

+14-11
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,10 @@ using namespace dyno::literals;
1111

1212

1313
// This benchmark measures the overhead of dispatching virtual calls using
14-
// different vtable policies.
14+
// different vtable policies, and inheritance.
1515

16-
template <typename ...InlineMethods>
16+
template <typename VTablePolicy>
1717
static void BM_dispatch4(benchmark::State& state) {
18-
using VTablePolicy = dyno::vtable<
19-
dyno::local<dyno::only<InlineMethods...>>,
20-
dyno::remote<dyno::everything_else>
21-
>;
2218
unsigned int x = 0;
2319
model<VTablePolicy> m{x};
2420
int const N = state.range(0);
@@ -33,10 +29,17 @@ static void BM_dispatch4(benchmark::State& state) {
3329
}
3430
}
3531

32+
template <typename ...InlineMethods>
33+
using inline_only = dyno::vtable<
34+
dyno::local<dyno::only<InlineMethods...>>,
35+
dyno::remote<dyno::everything_else>
36+
>;
37+
3638
static constexpr int N = 100;
37-
BENCHMARK(BM_dispatch4)->Arg(N);
38-
BENCHMARK_TEMPLATE(BM_dispatch4, decltype("f1"_s))->Arg(N);
39-
BENCHMARK_TEMPLATE(BM_dispatch4, decltype("f1"_s), decltype("f2"_s))->Arg(N);
40-
BENCHMARK_TEMPLATE(BM_dispatch4, decltype("f1"_s), decltype("f2"_s), decltype("f3"_s))->Arg(N);
41-
BENCHMARK_TEMPLATE(BM_dispatch4, decltype("f1"_s), decltype("f2"_s), decltype("f3"_s), decltype("f4"_s))->Arg(N);
39+
BENCHMARK_TEMPLATE(BM_dispatch4, inheritance_tag)->Arg(N);
40+
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<>)->Arg(N);
41+
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<decltype("f1"_s)>)->Arg(N);
42+
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<decltype("f1"_s), decltype("f2"_s)>)->Arg(N);
43+
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<decltype("f1"_s), decltype("f2"_s), decltype("f3"_s)>)->Arg(N);
44+
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<decltype("f1"_s), decltype("f2"_s), decltype("f3"_s), decltype("f4"_s)>)->Arg(N);
4245
BENCHMARK_MAIN();

Diff for: benchmark/vtable/model.hpp

+37
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <dyno.hpp>
99
#include <benchmark/benchmark.h>
10+
#include <memory>
1011
#include <utility>
1112
using namespace dyno::literals;
1213

@@ -46,4 +47,40 @@ struct model {
4647
dyno::poly<Concept, dyno::local_storage<8>, VTablePolicy> poly_;
4748
};
4849

50+
struct inheritance_tag { };
51+
52+
template <>
53+
struct model<inheritance_tag> {
54+
template <typename T>
55+
explicit model(T t)
56+
: self_{std::make_unique<model_t<T>>(std::move(t))}
57+
{ }
58+
59+
void f1() { self_->f1(); }
60+
void f2() { self_->f2(); }
61+
void f3() { self_->f3(); }
62+
void f4() { self_->f4(); }
63+
64+
private:
65+
struct concept_t {
66+
virtual void f1() = 0;
67+
virtual void f2() = 0;
68+
virtual void f3() = 0;
69+
virtual void f4() = 0;
70+
virtual ~concept_t() { }
71+
};
72+
73+
template <typename T>
74+
struct model_t : concept_t {
75+
model_t(T v) : value_{std::move(v)} { }
76+
void f1() override { ++value_; benchmark::DoNotOptimize(value_); }
77+
void f2() override { ++value_; benchmark::DoNotOptimize(value_); }
78+
void f3() override { ++value_; benchmark::DoNotOptimize(value_); }
79+
void f4() override { ++value_; benchmark::DoNotOptimize(value_); }
80+
T value_;
81+
};
82+
83+
std::unique_ptr<concept_t> self_;
84+
};
85+
4986
#endif // BENCHMARK_VTABLE_MODEL_HPP

0 commit comments

Comments
 (0)