inner_product.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2005-2006 Dan Marsden
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #include <boost/array.hpp>
  8. #include <boost/timer.hpp>
  9. #include <boost/fusion/algorithm/iteration/accumulate.hpp>
  10. #include <boost/fusion/algorithm/transformation/transform.hpp>
  11. #include <boost/fusion/container/vector.hpp>
  12. #include <boost/fusion/algorithm/transformation/zip.hpp>
  13. #include <boost/fusion/sequence/intrinsic/at.hpp>
  14. #include <boost/fusion/adapted/array.hpp>
  15. #include <boost/fusion/sequence/intrinsic/at.hpp>
  16. #include <boost/type_traits/remove_reference.hpp>
  17. #include <algorithm>
  18. #include <numeric>
  19. #include <functional>
  20. #include <iostream>
  21. #include <cmath>
  22. #include <limits>
  23. #ifdef _MSC_VER
  24. // inline aggressively
  25. # pragma inline_recursion(on) // turn on inline recursion
  26. # pragma inline_depth(255) // max inline depth
  27. #endif
  28. int const REPEAT_COUNT = 10;
  29. double const duration = 0.5;
  30. namespace
  31. {
  32. struct poly_add
  33. {
  34. template<typename Sig>
  35. struct result;
  36. template<typename Lhs, typename Rhs>
  37. struct result<poly_add(Lhs, Rhs)>
  38. : boost::remove_reference<Lhs>
  39. {};
  40. template<typename Lhs, typename Rhs>
  41. Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
  42. {
  43. return lhs + rhs;
  44. }
  45. };
  46. struct poly_mult
  47. {
  48. template<typename Sig>
  49. struct result;
  50. template<typename Lhs, typename Rhs>
  51. struct result<poly_mult(Lhs, Rhs)>
  52. : boost::remove_reference<Lhs>
  53. {};
  54. template<typename Lhs, typename Rhs>
  55. Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
  56. {
  57. return lhs * rhs;
  58. }
  59. };
  60. template<int N>
  61. double time_for_std_inner_product(int& j)
  62. {
  63. boost::timer tim;
  64. int i = 0;
  65. long long iter = 65536;
  66. long long counter, repeats;
  67. double result = (std::numeric_limits<double>::max)();
  68. double runtime = 0;
  69. double run;
  70. boost::array<int, N> arr1;
  71. boost::array<int, N> arr2;
  72. std::generate(arr1.begin(), arr1.end(), rand);
  73. std::generate(arr2.begin(), arr2.end(), rand);
  74. do
  75. {
  76. tim.restart();
  77. for(counter = 0; counter < iter; ++counter)
  78. {
  79. i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
  80. static_cast<void>(i);
  81. }
  82. runtime = tim.elapsed();
  83. iter *= 2;
  84. } while(runtime < duration);
  85. iter /= 2;
  86. // repeat test and report least value for consistency:
  87. for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
  88. {
  89. tim.restart();
  90. for(counter = 0; counter < iter; ++counter)
  91. {
  92. i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
  93. j += i;
  94. }
  95. run = tim.elapsed();
  96. result = (std::min)(run, result);
  97. }
  98. std::cout << i << std::endl;
  99. return result / iter;
  100. }
  101. template<int N>
  102. double time_for_fusion_inner_product(int& j)
  103. {
  104. boost::timer tim;
  105. int i = 0;
  106. long long iter = 65536;
  107. long long counter, repeats;
  108. double result = (std::numeric_limits<double>::max)();
  109. double runtime = 0;
  110. double run;
  111. boost::array<int, N> arr1;
  112. boost::array<int, N> arr2;
  113. std::generate(arr1.begin(), arr1.end(), rand);
  114. std::generate(arr2.begin(), arr2.end(), rand);
  115. do
  116. {
  117. tim.restart();
  118. for(counter = 0; counter < iter; ++counter)
  119. {
  120. i = boost::fusion::accumulate(
  121. boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
  122. static_cast<void>(i);
  123. }
  124. runtime = tim.elapsed();
  125. iter *= 2;
  126. } while(runtime < duration);
  127. iter /= 2;
  128. // repeat test and report least value for consistency:
  129. for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
  130. {
  131. tim.restart();
  132. for(counter = 0; counter < iter; ++counter)
  133. {
  134. i = boost::fusion::accumulate(
  135. boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
  136. j += i;
  137. }
  138. run = tim.elapsed();
  139. result = (std::min)(run, result);
  140. }
  141. std::cout << i << std::endl;
  142. return result / iter;
  143. }
  144. }
  145. int main()
  146. {
  147. int total = 0;
  148. int res;
  149. std::cout << "short inner_product std test " << time_for_std_inner_product<8>(res) << std::endl;
  150. total += res;
  151. std::cout << "short inner_product fusion test " << time_for_fusion_inner_product<8>(res) << std::endl;
  152. total += res;
  153. std::cout << "medium inner_product std test " << time_for_std_inner_product<64>(res) << std::endl;
  154. total += res;
  155. std::cout << "medium inner_product fusion test " << time_for_fusion_inner_product<64>(res) << std::endl;
  156. total += res;
  157. std::cout << "long inner_product std test " << time_for_std_inner_product<128>(res) << std::endl;
  158. total += res;
  159. std::cout << "long inner_product fusion test " << time_for_fusion_inner_product<128>(res) << std::endl;
  160. total += res;
  161. return total;
  162. }