annotate libcxx/benchmarks/function.bench.cpp @ 203:0d4b2609c30f

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 05 Jun 2021 11:18:24 +0900
parents 1d019706d866
children 1f2b6ac9f198
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include <cstdint>
anatofuz
parents:
diff changeset
10 #include <functional>
anatofuz
parents:
diff changeset
11 #include <memory>
anatofuz
parents:
diff changeset
12 #include <string>
anatofuz
parents:
diff changeset
13
anatofuz
parents:
diff changeset
14 #include "CartesianBenchmarks.h"
anatofuz
parents:
diff changeset
15 #include "benchmark/benchmark.h"
anatofuz
parents:
diff changeset
16 #include "test_macros.h"
anatofuz
parents:
diff changeset
17
anatofuz
parents:
diff changeset
18 namespace {
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 enum class FunctionType {
anatofuz
parents:
diff changeset
21 Null,
anatofuz
parents:
diff changeset
22 FunctionPointer,
anatofuz
parents:
diff changeset
23 MemberFunctionPointer,
anatofuz
parents:
diff changeset
24 MemberPointer,
anatofuz
parents:
diff changeset
25 SmallTrivialFunctor,
anatofuz
parents:
diff changeset
26 SmallNonTrivialFunctor,
anatofuz
parents:
diff changeset
27 LargeTrivialFunctor,
anatofuz
parents:
diff changeset
28 LargeNonTrivialFunctor
anatofuz
parents:
diff changeset
29 };
anatofuz
parents:
diff changeset
30
anatofuz
parents:
diff changeset
31 struct AllFunctionTypes : EnumValuesAsTuple<AllFunctionTypes, FunctionType, 8> {
anatofuz
parents:
diff changeset
32 static constexpr const char* Names[] = {"Null",
anatofuz
parents:
diff changeset
33 "FuncPtr",
anatofuz
parents:
diff changeset
34 "MemFuncPtr",
anatofuz
parents:
diff changeset
35 "MemPtr",
anatofuz
parents:
diff changeset
36 "SmallTrivialFunctor",
anatofuz
parents:
diff changeset
37 "SmallNonTrivialFunctor",
anatofuz
parents:
diff changeset
38 "LargeTrivialFunctor",
anatofuz
parents:
diff changeset
39 "LargeNonTrivialFunctor"};
anatofuz
parents:
diff changeset
40 };
anatofuz
parents:
diff changeset
41
anatofuz
parents:
diff changeset
42 enum class Opacity { kOpaque, kTransparent };
anatofuz
parents:
diff changeset
43
anatofuz
parents:
diff changeset
44 struct AllOpacity : EnumValuesAsTuple<AllOpacity, Opacity, 2> {
anatofuz
parents:
diff changeset
45 static constexpr const char* Names[] = {"Opaque", "Transparent"};
anatofuz
parents:
diff changeset
46 };
anatofuz
parents:
diff changeset
47
anatofuz
parents:
diff changeset
48 struct S {
anatofuz
parents:
diff changeset
49 int function() const { return 0; }
anatofuz
parents:
diff changeset
50 int field = 0;
anatofuz
parents:
diff changeset
51 };
anatofuz
parents:
diff changeset
52
anatofuz
parents:
diff changeset
53 int FunctionWithS(const S*) { return 0; }
anatofuz
parents:
diff changeset
54
anatofuz
parents:
diff changeset
55 struct SmallTrivialFunctor {
anatofuz
parents:
diff changeset
56 int operator()(const S*) const { return 0; }
anatofuz
parents:
diff changeset
57 };
anatofuz
parents:
diff changeset
58 struct SmallNonTrivialFunctor {
anatofuz
parents:
diff changeset
59 SmallNonTrivialFunctor() {}
anatofuz
parents:
diff changeset
60 SmallNonTrivialFunctor(const SmallNonTrivialFunctor&) {}
anatofuz
parents:
diff changeset
61 ~SmallNonTrivialFunctor() {}
anatofuz
parents:
diff changeset
62 int operator()(const S*) const { return 0; }
anatofuz
parents:
diff changeset
63 };
anatofuz
parents:
diff changeset
64 struct LargeTrivialFunctor {
anatofuz
parents:
diff changeset
65 LargeTrivialFunctor() {
anatofuz
parents:
diff changeset
66 // Do not spend time initializing the padding.
anatofuz
parents:
diff changeset
67 }
anatofuz
parents:
diff changeset
68 int padding[16];
anatofuz
parents:
diff changeset
69 int operator()(const S*) const { return 0; }
anatofuz
parents:
diff changeset
70 };
anatofuz
parents:
diff changeset
71 struct LargeNonTrivialFunctor {
anatofuz
parents:
diff changeset
72 int padding[16];
anatofuz
parents:
diff changeset
73 LargeNonTrivialFunctor() {
anatofuz
parents:
diff changeset
74 // Do not spend time initializing the padding.
anatofuz
parents:
diff changeset
75 }
anatofuz
parents:
diff changeset
76 LargeNonTrivialFunctor(const LargeNonTrivialFunctor&) {}
anatofuz
parents:
diff changeset
77 ~LargeNonTrivialFunctor() {}
anatofuz
parents:
diff changeset
78 int operator()(const S*) const { return 0; }
anatofuz
parents:
diff changeset
79 };
anatofuz
parents:
diff changeset
80
anatofuz
parents:
diff changeset
81 using Function = std::function<int(const S*)>;
anatofuz
parents:
diff changeset
82
anatofuz
parents:
diff changeset
83 TEST_ALWAYS_INLINE
anatofuz
parents:
diff changeset
84 inline Function MakeFunction(FunctionType type, bool opaque = false) {
anatofuz
parents:
diff changeset
85 switch (type) {
anatofuz
parents:
diff changeset
86 case FunctionType::Null:
anatofuz
parents:
diff changeset
87 return nullptr;
anatofuz
parents:
diff changeset
88 case FunctionType::FunctionPointer:
anatofuz
parents:
diff changeset
89 return maybeOpaque(FunctionWithS, opaque);
anatofuz
parents:
diff changeset
90 case FunctionType::MemberFunctionPointer:
anatofuz
parents:
diff changeset
91 return maybeOpaque(&S::function, opaque);
anatofuz
parents:
diff changeset
92 case FunctionType::MemberPointer:
anatofuz
parents:
diff changeset
93 return maybeOpaque(&S::field, opaque);
anatofuz
parents:
diff changeset
94 case FunctionType::SmallTrivialFunctor:
anatofuz
parents:
diff changeset
95 return maybeOpaque(SmallTrivialFunctor{}, opaque);
anatofuz
parents:
diff changeset
96 case FunctionType::SmallNonTrivialFunctor:
anatofuz
parents:
diff changeset
97 return maybeOpaque(SmallNonTrivialFunctor{}, opaque);
anatofuz
parents:
diff changeset
98 case FunctionType::LargeTrivialFunctor:
anatofuz
parents:
diff changeset
99 return maybeOpaque(LargeTrivialFunctor{}, opaque);
anatofuz
parents:
diff changeset
100 case FunctionType::LargeNonTrivialFunctor:
anatofuz
parents:
diff changeset
101 return maybeOpaque(LargeNonTrivialFunctor{}, opaque);
anatofuz
parents:
diff changeset
102 }
anatofuz
parents:
diff changeset
103 }
anatofuz
parents:
diff changeset
104
anatofuz
parents:
diff changeset
105 template <class Opacity, class FunctionType>
anatofuz
parents:
diff changeset
106 struct ConstructAndDestroy {
anatofuz
parents:
diff changeset
107 static void run(benchmark::State& state) {
anatofuz
parents:
diff changeset
108 for (auto _ : state) {
anatofuz
parents:
diff changeset
109 if (Opacity() == ::Opacity::kOpaque) {
anatofuz
parents:
diff changeset
110 benchmark::DoNotOptimize(MakeFunction(FunctionType(), true));
anatofuz
parents:
diff changeset
111 } else {
anatofuz
parents:
diff changeset
112 MakeFunction(FunctionType());
anatofuz
parents:
diff changeset
113 }
anatofuz
parents:
diff changeset
114 }
anatofuz
parents:
diff changeset
115 }
anatofuz
parents:
diff changeset
116
anatofuz
parents:
diff changeset
117 static std::string name() {
anatofuz
parents:
diff changeset
118 return "BM_ConstructAndDestroy" + FunctionType::name() + Opacity::name();
anatofuz
parents:
diff changeset
119 }
anatofuz
parents:
diff changeset
120 };
anatofuz
parents:
diff changeset
121
anatofuz
parents:
diff changeset
122 template <class FunctionType>
anatofuz
parents:
diff changeset
123 struct Copy {
anatofuz
parents:
diff changeset
124 static void run(benchmark::State& state) {
anatofuz
parents:
diff changeset
125 auto value = MakeFunction(FunctionType());
anatofuz
parents:
diff changeset
126 for (auto _ : state) {
anatofuz
parents:
diff changeset
127 benchmark::DoNotOptimize(value);
anatofuz
parents:
diff changeset
128 auto copy = value; // NOLINT
anatofuz
parents:
diff changeset
129 benchmark::DoNotOptimize(copy);
anatofuz
parents:
diff changeset
130 }
anatofuz
parents:
diff changeset
131 }
anatofuz
parents:
diff changeset
132
anatofuz
parents:
diff changeset
133 static std::string name() { return "BM_Copy" + FunctionType::name(); }
anatofuz
parents:
diff changeset
134 };
anatofuz
parents:
diff changeset
135
anatofuz
parents:
diff changeset
136 template <class FunctionType>
anatofuz
parents:
diff changeset
137 struct Move {
anatofuz
parents:
diff changeset
138 static void run(benchmark::State& state) {
anatofuz
parents:
diff changeset
139 Function values[2] = {MakeFunction(FunctionType())};
anatofuz
parents:
diff changeset
140 int i = 0;
anatofuz
parents:
diff changeset
141 for (auto _ : state) {
anatofuz
parents:
diff changeset
142 benchmark::DoNotOptimize(values);
anatofuz
parents:
diff changeset
143 benchmark::DoNotOptimize(values[i ^ 1] = std::move(values[i]));
anatofuz
parents:
diff changeset
144 i ^= 1;
anatofuz
parents:
diff changeset
145 }
anatofuz
parents:
diff changeset
146 }
anatofuz
parents:
diff changeset
147
anatofuz
parents:
diff changeset
148 static std::string name() {
anatofuz
parents:
diff changeset
149 return "BM_Move" + FunctionType::name();
anatofuz
parents:
diff changeset
150 }
anatofuz
parents:
diff changeset
151 };
anatofuz
parents:
diff changeset
152
anatofuz
parents:
diff changeset
153 template <class Function1, class Function2>
anatofuz
parents:
diff changeset
154 struct Swap {
anatofuz
parents:
diff changeset
155 static void run(benchmark::State& state) {
anatofuz
parents:
diff changeset
156 Function values[2] = {MakeFunction(Function1()), MakeFunction(Function2())};
anatofuz
parents:
diff changeset
157 for (auto _ : state) {
anatofuz
parents:
diff changeset
158 benchmark::DoNotOptimize(values);
anatofuz
parents:
diff changeset
159 values[0].swap(values[1]);
anatofuz
parents:
diff changeset
160 }
anatofuz
parents:
diff changeset
161 }
anatofuz
parents:
diff changeset
162
anatofuz
parents:
diff changeset
163 static bool skip() { return Function1() > Function2(); }
anatofuz
parents:
diff changeset
164
anatofuz
parents:
diff changeset
165 static std::string name() {
anatofuz
parents:
diff changeset
166 return "BM_Swap" + Function1::name() + Function2::name();
anatofuz
parents:
diff changeset
167 }
anatofuz
parents:
diff changeset
168 };
anatofuz
parents:
diff changeset
169
anatofuz
parents:
diff changeset
170 template <class FunctionType>
anatofuz
parents:
diff changeset
171 struct OperatorBool {
anatofuz
parents:
diff changeset
172 static void run(benchmark::State& state) {
anatofuz
parents:
diff changeset
173 auto f = MakeFunction(FunctionType());
anatofuz
parents:
diff changeset
174 for (auto _ : state) {
anatofuz
parents:
diff changeset
175 benchmark::DoNotOptimize(f);
anatofuz
parents:
diff changeset
176 benchmark::DoNotOptimize(static_cast<bool>(f));
anatofuz
parents:
diff changeset
177 }
anatofuz
parents:
diff changeset
178 }
anatofuz
parents:
diff changeset
179
anatofuz
parents:
diff changeset
180 static std::string name() { return "BM_OperatorBool" + FunctionType::name(); }
anatofuz
parents:
diff changeset
181 };
anatofuz
parents:
diff changeset
182
anatofuz
parents:
diff changeset
183 template <class FunctionType>
anatofuz
parents:
diff changeset
184 struct Invoke {
anatofuz
parents:
diff changeset
185 static void run(benchmark::State& state) {
anatofuz
parents:
diff changeset
186 S s;
anatofuz
parents:
diff changeset
187 const auto value = MakeFunction(FunctionType());
anatofuz
parents:
diff changeset
188 for (auto _ : state) {
anatofuz
parents:
diff changeset
189 benchmark::DoNotOptimize(value);
anatofuz
parents:
diff changeset
190 benchmark::DoNotOptimize(value(&s));
anatofuz
parents:
diff changeset
191 }
anatofuz
parents:
diff changeset
192 }
anatofuz
parents:
diff changeset
193
anatofuz
parents:
diff changeset
194 static bool skip() { return FunctionType() == ::FunctionType::Null; }
anatofuz
parents:
diff changeset
195
anatofuz
parents:
diff changeset
196 static std::string name() { return "BM_Invoke" + FunctionType::name(); }
anatofuz
parents:
diff changeset
197 };
anatofuz
parents:
diff changeset
198
anatofuz
parents:
diff changeset
199 template <class FunctionType>
anatofuz
parents:
diff changeset
200 struct InvokeInlined {
anatofuz
parents:
diff changeset
201 static void run(benchmark::State& state) {
anatofuz
parents:
diff changeset
202 S s;
anatofuz
parents:
diff changeset
203 for (auto _ : state) {
anatofuz
parents:
diff changeset
204 MakeFunction(FunctionType())(&s);
anatofuz
parents:
diff changeset
205 }
anatofuz
parents:
diff changeset
206 }
anatofuz
parents:
diff changeset
207
anatofuz
parents:
diff changeset
208 static bool skip() { return FunctionType() == ::FunctionType::Null; }
anatofuz
parents:
diff changeset
209
anatofuz
parents:
diff changeset
210 static std::string name() {
anatofuz
parents:
diff changeset
211 return "BM_InvokeInlined" + FunctionType::name();
anatofuz
parents:
diff changeset
212 }
anatofuz
parents:
diff changeset
213 };
anatofuz
parents:
diff changeset
214
anatofuz
parents:
diff changeset
215 } // namespace
anatofuz
parents:
diff changeset
216
anatofuz
parents:
diff changeset
217 int main(int argc, char** argv) {
anatofuz
parents:
diff changeset
218 benchmark::Initialize(&argc, argv);
anatofuz
parents:
diff changeset
219 if (benchmark::ReportUnrecognizedArguments(argc, argv))
anatofuz
parents:
diff changeset
220 return 1;
anatofuz
parents:
diff changeset
221
anatofuz
parents:
diff changeset
222 makeCartesianProductBenchmark<ConstructAndDestroy, AllOpacity,
anatofuz
parents:
diff changeset
223 AllFunctionTypes>();
anatofuz
parents:
diff changeset
224 makeCartesianProductBenchmark<Copy, AllFunctionTypes>();
anatofuz
parents:
diff changeset
225 makeCartesianProductBenchmark<Move, AllFunctionTypes>();
anatofuz
parents:
diff changeset
226 makeCartesianProductBenchmark<Swap, AllFunctionTypes, AllFunctionTypes>();
anatofuz
parents:
diff changeset
227 makeCartesianProductBenchmark<OperatorBool, AllFunctionTypes>();
anatofuz
parents:
diff changeset
228 makeCartesianProductBenchmark<Invoke, AllFunctionTypes>();
anatofuz
parents:
diff changeset
229 makeCartesianProductBenchmark<InvokeInlined, AllFunctionTypes>();
anatofuz
parents:
diff changeset
230 benchmark::RunSpecifiedBenchmarks();
anatofuz
parents:
diff changeset
231 }