123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2005-2006 Dan Marsden
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- ==============================================================================*/
- #include <boost/array.hpp>
- #include <boost/timer.hpp>
- #include <boost/fusion/algorithm/iteration/accumulate.hpp>
- #include <boost/fusion/algorithm/transformation/transform.hpp>
- #include <boost/fusion/container/vector.hpp>
- #include <boost/fusion/algorithm/transformation/zip.hpp>
- #include <boost/fusion/sequence/intrinsic/at.hpp>
- #include <boost/fusion/adapted/array.hpp>
- #include <boost/fusion/sequence/intrinsic/at.hpp>
- #include <boost/type_traits/remove_reference.hpp>
- #include <algorithm>
- #include <numeric>
- #include <functional>
- #include <iostream>
- #include <cmath>
- #include <limits>
- #ifdef _MSC_VER
- // inline aggressively
- # pragma inline_recursion(on) // turn on inline recursion
- # pragma inline_depth(255) // max inline depth
- #endif
- int const REPEAT_COUNT = 10;
- double const duration = 0.5;
- namespace
- {
- struct poly_add
- {
- template<typename Sig>
- struct result;
- template<typename Lhs, typename Rhs>
- struct result<poly_add(Lhs, Rhs)>
- : boost::remove_reference<Lhs>
- {};
- template<typename Lhs, typename Rhs>
- Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
- {
- return lhs + rhs;
- }
- };
- struct poly_mult
- {
- template<typename Sig>
- struct result;
- template<typename Lhs, typename Rhs>
- struct result<poly_mult(Lhs, Rhs)>
- : boost::remove_reference<Lhs>
- {};
- template<typename Lhs, typename Rhs>
- Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
- {
- return lhs * rhs;
- }
- };
- template<int N>
- double time_for_std_inner_product(int& j)
- {
- boost::timer tim;
- int i = 0;
- long long iter = 65536;
- long long counter, repeats;
- double result = (std::numeric_limits<double>::max)();
- double runtime = 0;
- double run;
- boost::array<int, N> arr1;
- boost::array<int, N> arr2;
- std::generate(arr1.begin(), arr1.end(), rand);
- std::generate(arr2.begin(), arr2.end(), rand);
- do
- {
- tim.restart();
- for(counter = 0; counter < iter; ++counter)
- {
- i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
- static_cast<void>(i);
- }
- runtime = tim.elapsed();
- iter *= 2;
- } while(runtime < duration);
- iter /= 2;
- // repeat test and report least value for consistency:
- for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
- {
- tim.restart();
- for(counter = 0; counter < iter; ++counter)
- {
- i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
- j += i;
- }
- run = tim.elapsed();
- result = (std::min)(run, result);
- }
- std::cout << i << std::endl;
- return result / iter;
- }
- template<int N>
- double time_for_fusion_inner_product(int& j)
- {
- boost::timer tim;
- int i = 0;
- long long iter = 65536;
- long long counter, repeats;
- double result = (std::numeric_limits<double>::max)();
- double runtime = 0;
- double run;
- boost::array<int, N> arr1;
- boost::array<int, N> arr2;
- std::generate(arr1.begin(), arr1.end(), rand);
- std::generate(arr2.begin(), arr2.end(), rand);
- do
- {
- tim.restart();
- for(counter = 0; counter < iter; ++counter)
- {
- i = boost::fusion::accumulate(
- boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
- static_cast<void>(i);
- }
- runtime = tim.elapsed();
- iter *= 2;
- } while(runtime < duration);
- iter /= 2;
- // repeat test and report least value for consistency:
- for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
- {
- tim.restart();
- for(counter = 0; counter < iter; ++counter)
- {
- i = boost::fusion::accumulate(
- boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
- j += i;
- }
- run = tim.elapsed();
- result = (std::min)(run, result);
- }
- std::cout << i << std::endl;
- return result / iter;
- }
- }
- int main()
- {
- int total = 0;
- int res;
- std::cout << "short inner_product std test " << time_for_std_inner_product<8>(res) << std::endl;
- total += res;
- std::cout << "short inner_product fusion test " << time_for_fusion_inner_product<8>(res) << std::endl;
- total += res;
- std::cout << "medium inner_product std test " << time_for_std_inner_product<64>(res) << std::endl;
- total += res;
- std::cout << "medium inner_product fusion test " << time_for_fusion_inner_product<64>(res) << std::endl;
- total += res;
- std::cout << "long inner_product std test " << time_for_std_inner_product<128>(res) << std::endl;
- total += res;
- std::cout << "long inner_product fusion test " << time_for_fusion_inner_product<128>(res) << std::endl;
- total += res;
- return total;
- }
|