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; |
31 | T operator()(Iterator first,Iterator last) |
32 | { |
33 | return std::accumulate(first,last,T()); |
34 | } |
35 | }; |
36 | |
37 | template<typename Iterator,typename T> |
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 | |
70 | int main() |
71 | { |
72 | try |
73 | { |
74 | const int s = 1001; |
75 | std::vector<int> vec; |
76 | vec.reserve(n: s); |
77 | for (int i=0; i<s;++i) |
78 | vec.push_back(x: 1); |
79 | int r = parallel_accumulate(first: vec.begin(), last: vec.end(),init: 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" |
98 | int main() |
99 | { |
100 | return 0; |
101 | } |
102 | #endif |
103 | |