• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <boost/fusion/sequence/intrinsic/at.hpp>
18 
19 #include <boost/type_traits/remove_reference.hpp>
20 
21 #include <algorithm>
22 #include <numeric>
23 #include <functional>
24 #include <iostream>
25 #include <cmath>
26 #include <limits>
27 
28 #ifdef _MSC_VER
29 // inline aggressively
30 # pragma inline_recursion(on) // turn on inline recursion
31 # pragma inline_depth(255)    // max inline depth
32 #endif
33 
34 int const REPEAT_COUNT = 10;
35 
36 double const duration = 0.5;
37 
38 namespace
39 {
40     struct poly_add
41     {
42         template<typename Sig>
43         struct result;
44 
45         template<typename Lhs, typename Rhs>
46         struct result<poly_add(Lhs, Rhs)>
47             : boost::remove_reference<Lhs>
48         {};
49 
50         template<typename Lhs, typename Rhs>
operator ()__anonf9589a9f0111::poly_add51         Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
52         {
53             return lhs + rhs;
54         }
55     };
56 
57     struct poly_mult
58     {
59         template<typename Sig>
60         struct result;
61 
62         template<typename Lhs, typename Rhs>
63         struct result<poly_mult(Lhs, Rhs)>
64             : boost::remove_reference<Lhs>
65         {};
66 
67         template<typename Lhs, typename Rhs>
operator ()__anonf9589a9f0111::poly_mult68         Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
69         {
70             return lhs * rhs;
71         }
72     };
73 
74     template<int N>
time_for_std_inner_product(int & j)75     double time_for_std_inner_product(int& j)
76     {
77         boost::timer tim;
78         int i = 0;
79         long long iter = 65536;
80         long long counter, repeats;
81         double result = (std::numeric_limits<double>::max)();
82         double runtime = 0;
83         double run;
84         boost::array<int, N> arr1;
85         boost::array<int, N> arr2;
86         std::generate(arr1.begin(), arr1.end(), rand);
87         std::generate(arr2.begin(), arr2.end(), rand);
88         do
89         {
90             tim.restart();
91             for(counter = 0; counter < iter; ++counter)
92             {
93                 i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
94                 static_cast<void>(i);
95             }
96             runtime = tim.elapsed();
97             iter *= 2;
98         } while(runtime < duration);
99         iter /= 2;
100 
101         // repeat test and report least value for consistency:
102         for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
103         {
104             tim.restart();
105             for(counter = 0; counter < iter; ++counter)
106             {
107                 i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
108                 j += i;
109             }
110             run = tim.elapsed();
111             result = (std::min)(run, result);
112         }
113         std::cout << i << std::endl;
114         return result / iter;
115     }
116 
117     template<int N>
time_for_fusion_inner_product(int & j)118     double time_for_fusion_inner_product(int& j)
119     {
120         boost::timer tim;
121         int i = 0;
122         long long iter = 65536;
123         long long counter, repeats;
124         double result = (std::numeric_limits<double>::max)();
125         double runtime = 0;
126         double run;
127         boost::array<int, N> arr1;
128         boost::array<int, N> arr2;
129         std::generate(arr1.begin(), arr1.end(), rand);
130         std::generate(arr2.begin(), arr2.end(), rand);
131         do
132         {
133             tim.restart();
134             for(counter = 0; counter < iter; ++counter)
135             {
136                 i = boost::fusion::accumulate(
137                     boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
138                 static_cast<void>(i);
139             }
140             runtime = tim.elapsed();
141             iter *= 2;
142         } while(runtime < duration);
143         iter /= 2;
144 
145         // repeat test and report least value for consistency:
146         for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
147         {
148             tim.restart();
149             for(counter = 0; counter < iter; ++counter)
150             {
151                 i = boost::fusion::accumulate(
152                     boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
153                 j += i;
154             }
155             run = tim.elapsed();
156             result = (std::min)(run, result);
157         }
158         std::cout << i << std::endl;
159         return result / iter;
160     }
161 }
162 
main()163 int main()
164 {
165     int total = 0;
166     int res;
167 
168     std::cout << "short inner_product std test " << time_for_std_inner_product<8>(res) << std::endl;
169     total += res;
170     std::cout << "short inner_product fusion test " << time_for_fusion_inner_product<8>(res) << std::endl;
171     total += res;
172 
173     std::cout << "medium inner_product std test " << time_for_std_inner_product<64>(res) << std::endl;
174     total += res;
175     std::cout << "medium inner_product fusion test " << time_for_fusion_inner_product<64>(res) << std::endl;
176     total += res;
177 
178     std::cout << "long inner_product std test " << time_for_std_inner_product<128>(res) << std::endl;
179     total += res;
180     std::cout << "long inner_product fusion test " << time_for_fusion_inner_product<128>(res) << std::endl;
181     total += res;
182 
183     return total;
184 }
185