]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fusion/example/performance/accumulate.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / fusion / example / performance / accumulate.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2005-2006 Dan Marsden
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #include <boost/array.hpp>
9 #include <boost/timer.hpp>
10
11 #include <boost/fusion/algorithm/iteration/accumulate.hpp>
12 #include <boost/fusion/algorithm/transformation/transform.hpp>
13 #include <boost/fusion/container/vector.hpp>
14 #include <boost/fusion/algorithm/transformation/zip.hpp>
15 #include <boost/fusion/sequence/intrinsic/at.hpp>
16 #include <boost/fusion/adapted/array.hpp>
17
18 #include <boost/type_traits/remove_reference.hpp>
19
20 #include <algorithm>
21 #include <numeric>
22 #include <functional>
23 #include <iostream>
24 #include <cmath>
25 #include <limits>
26
27 #ifdef _MSC_VER
28 // inline aggressively
29 # pragma inline_recursion(on) // turn on inline recursion
30 # pragma inline_depth(255) // max inline depth
31 #endif
32
33 int const REPEAT_COUNT = 10;
34
35 double const duration = 0.5;
36
37 namespace
38 {
39 template<int N>
40 double time_for_std_accumulate(int& j)
41 {
42 boost::timer tim;
43 int i = 0;
44 long long iter = 65536;
45 long long counter, repeats;
46 double result = (std::numeric_limits<double>::max)();
47 double runtime = 0;
48 double run;
49 boost::array<int, N> arr;
50 std::generate(arr.begin(), arr.end(), rand);
51 do
52 {
53 tim.restart();
54 for(counter = 0; counter < iter; ++counter)
55 {
56 i = std::accumulate(arr.begin(), arr.end(), 0);
57 static_cast<void>(i);
58 }
59 runtime = tim.elapsed();
60 iter *= 2;
61 } while(runtime < duration);
62 iter /= 2;
63
64 // repeat test and report least value for consistency:
65 for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
66 {
67 tim.restart();
68 for(counter = 0; counter < iter; ++counter)
69 {
70 i = std::accumulate(arr.begin(), arr.end(), 0);
71 j += i;
72 }
73 run = tim.elapsed();
74 result = (std::min)(run, result);
75 }
76 std::cout << i << std::endl;
77 return result / iter;
78 }
79
80 struct poly_add
81 {
82 template<typename Sig>
83 struct result;
84
85 template<typename Lhs, typename Rhs>
86 struct result<poly_add(Lhs,Rhs)>
87 : boost::remove_reference<Lhs>
88 {};
89
90 template<typename Lhs, typename Rhs>
91 Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
92 {
93 return lhs + rhs;
94 }
95 };
96
97 struct poly_mult
98 {
99 template<typename Sig>
100 struct result;
101
102 template<typename Lhs, typename Rhs>
103 struct result<poly_mult(Lhs, Rhs)>
104 : boost::remove_reference<Lhs>
105 {};
106
107 template<typename Lhs, typename Rhs>
108 Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
109 {
110 return lhs * rhs;
111 }
112 };
113
114 template<int N>
115 double time_for_fusion_accumulate(int& j)
116 {
117 boost::timer tim;
118 int i = 0;
119 long long iter = 65536;
120 long long counter, repeats;
121 double result = (std::numeric_limits<double>::max)();
122 double runtime = 0;
123 double run;
124 boost::array<int, N> arr;
125 std::generate(arr.begin(), arr.end(), rand);
126 do
127 {
128 tim.restart();
129 for(counter = 0; counter < iter; ++counter)
130 {
131 i = boost::fusion::accumulate(arr, 0, poly_add());
132 static_cast<void>(i);
133 }
134 runtime = tim.elapsed();
135 iter *= 2;
136 } while(runtime < duration);
137 iter /= 2;
138
139 std::cout << iter << " iterations" << std::endl;
140
141 // repeat test and report least value for consistency:
142 for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
143 {
144 tim.restart();
145 for(counter = 0; counter < iter; ++counter)
146 {
147 i = boost::fusion::accumulate(arr, 0, poly_add());
148 j += i;
149 }
150 run = tim.elapsed();
151 result = (std::min)(run, result);
152 std::cout << ".";
153 std::cout.flush();
154 }
155 std::cout << i << std::endl;
156 return result / iter;
157 }
158
159 #if 0
160 template<int N>
161 double time_for_std_inner_product(int& j)
162 {
163 boost::timer tim;
164 int i = 0;
165 long long iter = 65536;
166 long long counter, repeats;
167 double result = (std::numeric_limits<double>::max)();
168 double runtime = 0;
169 double run;
170 boost::array<int, N> arr1;
171 boost::array<int, N> arr2;
172 std::generate(arr1.begin(), arr1.end(), rand);
173 std::generate(arr2.begin(), arr2.end(), rand);
174 do
175 {
176 tim.restart();
177 for(counter = 0; counter < iter; ++counter)
178 {
179 i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
180 static_cast<void>(i);
181 }
182 runtime = tim.elapsed();
183 iter *= 2;
184 } while(runtime < duration);
185 iter /= 2;
186
187 // repeat test and report least value for consistency:
188 for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
189 {
190 tim.restart();
191 for(counter = 0; counter < iter; ++counter)
192 {
193 i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
194 j += i;
195 }
196 run = tim.elapsed();
197 result = (std::min)(run, result);
198 }
199 std::cout << i << std::endl;
200 return result / iter;
201 }
202
203 template<int N>
204 double time_for_fusion_inner_product(int& j)
205 {
206 boost::timer tim;
207 int i = 0;
208 long long iter = 65536;
209 long long counter, repeats;
210 double result = (std::numeric_limits<double>::max)();
211 double runtime = 0;
212 double run;
213 boost::array<int, N> arr1;
214 boost::array<int, N> arr2;
215 std::generate(arr1.begin(), arr1.end(), rand);
216 std::generate(arr2.begin(), arr2.end(), rand);
217 do
218 {
219 tim.restart();
220 for(counter = 0; counter < iter; ++counter)
221 {
222 i = boost::fusion::accumulate(
223 boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
224 static_cast<void>(i);
225 }
226 runtime = tim.elapsed();
227 iter *= 2;
228 } while(runtime < duration);
229 iter /= 2;
230
231 // repeat test and report least value for consistency:
232 for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
233 {
234 tim.restart();
235 for(counter = 0; counter < iter; ++counter)
236 {
237 i = boost::fusion::accumulate(
238 boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
239 j += i;
240 }
241 run = tim.elapsed();
242 result = (std::min)(run, result);
243 }
244 std::cout << i << std::endl;
245 return result / iter;
246 }
247
248 struct poly_combine
249 {
250 template<typename Lhs, typename Rhs>
251 struct result
252 {
253 typedef Lhs type;
254 };
255
256 template<typename Lhs, typename Rhs>
257 typename result<Lhs,Rhs>::type
258 operator()(const Lhs& lhs, const Rhs& rhs) const
259 {
260 return lhs + boost::fusion::at_c<0>(rhs) * boost::fusion::at_c<1>(rhs);
261 }
262 };
263
264 template<int N>
265 double time_for_fusion_inner_product2(int& j)
266 {
267 boost::timer tim;
268 int i = 0;
269 long long iter = 65536;
270 long long counter, repeats;
271 double result = (std::numeric_limits<double>::max)();
272 double runtime = 0;
273 double run;
274 boost::array<int, N> arr1;
275 boost::array<int, N> arr2;
276 std::generate(arr1.begin(), arr1.end(), rand);
277 std::generate(arr2.begin(), arr2.end(), rand);
278 do
279 {
280 tim.restart();
281 for(counter = 0; counter < iter; ++counter)
282 {
283 i = boost::fusion::accumulate(
284 boost::fusion::zip(arr1, arr2), 0, poly_combine());
285 static_cast<void>(i);
286 }
287 runtime = tim.elapsed();
288 iter *= 2;
289 } while(runtime < duration);
290 iter /= 2;
291
292 std::cout << iter << " iterations" << std::endl;
293
294 // repeat test and report least value for consistency:
295 for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
296 {
297 tim.restart();
298 for(counter = 0; counter < iter; ++counter)
299 {
300 i = boost::fusion::accumulate(
301 boost::fusion::zip(arr1, arr2), 0, poly_combine());
302 j += i;
303 }
304 run = tim.elapsed();
305 result = (std::min)(run, result);
306 }
307 std::cout << i << std::endl;
308 return result / iter;
309 }
310 #endif
311 }
312
313 int main()
314 {
315 int total = 0;
316 int res;
317 std::cout << "short accumulate std test " << time_for_std_accumulate<8>(res) << std::endl;
318 total += res;
319 std::cout << "short accumulate fusion test " << time_for_fusion_accumulate<8>(res) << std::endl;
320 total += res;
321
322 std::cout << "medium accumulate std test " << time_for_std_accumulate<64>(res) << std::endl;
323 total += res;
324 std::cout << "medium accumulate fusion test " << time_for_fusion_accumulate<64>(res) << std::endl;
325 total += res;
326
327 std::cout << "long accumulate std test " << time_for_std_accumulate<128>(res) << std::endl;
328 total += res;
329 std::cout << "long accumulate fusion test " << time_for_fusion_accumulate<128>(res) << std::endl;
330 total += res;
331
332 #if 0
333 std::cout << "short inner_product std test " << time_for_std_inner_product<8>(res) << std::endl;
334 total += res;
335 std::cout << "short inner_product fusion test " << time_for_fusion_inner_product<8>(res) << std::endl;
336 total += res;
337 std::cout << "short inner_product fusion 2 test " << time_for_fusion_inner_product2<8>(res) << std::endl;
338 total += res;
339
340 std::cout << "medium inner_product std test " << time_for_std_inner_product<64>(res) << std::endl;
341 total += res;
342 std::cout << "medium inner_product fusion test " << time_for_fusion_inner_product<64>(res) << std::endl;
343 total += res;
344 std::cout << "medium inner_product fusion 2 test " << time_for_fusion_inner_product2<64>(res) << std::endl;
345 total += res;
346
347
348 std::cout << "long inner_product std test " << time_for_std_inner_product<128>(res) << std::endl;
349 total += res;
350 std::cout << "long inner_product fusion test " << time_for_fusion_inner_product<128>(res) << std::endl;
351 total += res;
352 std::cout << "long inner_product fusion 2 test " << time_for_fusion_inner_product2<128>(res) << std::endl;
353 total += res;
354 #endif
355
356 return total;
357 }