parallel_accumulate.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. #include <boost/config.hpp>
  6. #define BOOST_THREAD_VERSION 4
  7. #define BOOST_THREAD_PROVIDES_EXECUTORS
  8. #define BOOST_THREAD_USES_LOG_THREAD_ID
  9. #define BOOST_THREAD_QUEUE_DEPRECATE_OLD
  10. #if ! defined BOOST_NO_CXX11_DECLTYPE
  11. #define BOOST_RESULT_OF_USE_DECLTYPE
  12. #endif
  13. #include <boost/thread/executors/basic_thread_pool.hpp>
  14. #include <boost/thread/future.hpp>
  15. #include <numeric>
  16. #include <algorithm>
  17. #include <functional>
  18. #include <iostream>
  19. #include <vector>
  20. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  21. template<typename Iterator,typename T>
  22. struct accumulate_block
  23. {
  24. //typedef T result_type;
  25. T operator()(Iterator first,Iterator last)
  26. {
  27. return std::accumulate(first,last,T());
  28. }
  29. };
  30. template<typename Iterator,typename T>
  31. T parallel_accumulate(Iterator first,Iterator last,T init)
  32. {
  33. unsigned long const length=static_cast<unsigned long>(std::distance(first,last));
  34. if(!length)
  35. return init;
  36. unsigned long const block_size=25;
  37. unsigned long const num_blocks=(length+block_size-1)/block_size;
  38. boost::csbl::vector<boost::future<T> > futures(num_blocks-1);
  39. boost::basic_thread_pool pool;
  40. Iterator block_start=first;
  41. for(unsigned long i=0;i<(num_blocks-1);++i)
  42. {
  43. Iterator block_end=block_start;
  44. std::advance(block_end,block_size);
  45. futures[i]=boost::async(pool, accumulate_block<Iterator,T>(), block_start, block_end);
  46. block_start=block_end;
  47. }
  48. T last_result=accumulate_block<Iterator,T>()(block_start,last);
  49. T result=init;
  50. for(unsigned long i=0;i<(num_blocks-1);++i)
  51. {
  52. result+=futures[i].get();
  53. }
  54. result += last_result;
  55. return result;
  56. }
  57. int main()
  58. {
  59. try
  60. {
  61. const int s = 1001;
  62. std::vector<int> vec;
  63. vec.reserve(s);
  64. for (int i=0; i<s;++i)
  65. vec.push_back(1);
  66. int r = parallel_accumulate(vec.begin(), vec.end(),0);
  67. std::cout << r << std::endl;
  68. }
  69. catch (std::exception& ex)
  70. {
  71. std::cout << "ERROR= " << ex.what() << "" << std::endl;
  72. return 1;
  73. }
  74. catch (...)
  75. {
  76. std::cout << " ERROR= exception thrown" << std::endl;
  77. return 2;
  78. }
  79. return 0;
  80. }
  81. #else
  82. ///#warning "This compiler doesn't supports variadics"
  83. int main()
  84. {
  85. return 0;
  86. }
  87. #endif