1 // Copyright (C) 2014 Vicente Botet
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #include <boost/config.hpp>
7 
8 #define BOOST_THREAD_VERSION 4
9 #define BOOST_THREAD_PROVIDES_EXECUTORS
10 #define BOOST_THREAD_USES_LOG_THREAD_ID
11 #define BOOST_THREAD_QUEUE_DEPRECATE_OLD
12 #if ! defined  BOOST_NO_CXX11_DECLTYPE
13 #define BOOST_RESULT_OF_USE_DECLTYPE
14 #endif
15 
16 #include <boost/thread/executors/basic_thread_pool.hpp>
17 #include <boost/thread/future.hpp>
18 
19 #include <numeric>
20 #include <algorithm>
21 #include <functional>
22 #include <iostream>
23 #include <vector>
24 
25 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
26 
27 template<typename Iterator,typename T>
28 struct accumulate_block
29 {
30     //typedef T result_type;
operator ()accumulate_block31     T operator()(Iterator first,Iterator last)
32     {
33         return std::accumulate(first,last,T());
34     }
35 };
36 
37 template<typename Iterator,typename T>
parallel_accumulate(Iterator first,Iterator last,T init)38 T parallel_accumulate(Iterator first,Iterator last,T init)
39 {
40     unsigned long const length=static_cast<unsigned long>(std::distance(first,last));
41 
42     if(!length)
43         return init;
44 
45     unsigned long const block_size=25;
46     unsigned long const num_blocks=(length+block_size-1)/block_size;
47 
48     boost::csbl::vector<boost::future<T> > futures(num_blocks-1);
49     boost::basic_thread_pool pool;
50 
51     Iterator block_start=first;
52     for(unsigned long i=0;i<(num_blocks-1);++i)
53     {
54         Iterator block_end=block_start;
55         std::advance(block_end,block_size);
56         futures[i]=boost::async(pool, accumulate_block<Iterator,T>(), block_start, block_end);
57         block_start=block_end;
58     }
59     T last_result=accumulate_block<Iterator,T>()(block_start,last);
60     T result=init;
61     for(unsigned long i=0;i<(num_blocks-1);++i)
62     {
63         result+=futures[i].get();
64     }
65     result += last_result;
66     return result;
67 }
68 
69 
main()70 int main()
71 {
72   try
73   {
74     const int s = 1001;
75     std::vector<int> vec;
76     vec.reserve(s);
77     for (int i=0; i<s;++i)
78       vec.push_back(1);
79     int r = parallel_accumulate(vec.begin(), vec.end(),0);
80     std::cout << r << std::endl;
81 
82   }
83   catch (std::exception& ex)
84   {
85     std::cout << "ERROR= " << ex.what() << "" << std::endl;
86     return 1;
87   }
88   catch (...)
89   {
90     std::cout << " ERROR= exception thrown" << std::endl;
91     return 2;
92   }
93   return 0;
94 }
95 
96 #else
97 ///#warning "This compiler doesn't supports variadics"
main()98 int main()
99 {
100   return 0;
101 }
102 #endif
103