#include <iostream>#include<algorithm>#include<thread>#include<functional>using namespacestd;template<typename Iterator, TypeName t>structaccumulate_block{void operator() (Iterator first, Iterator last, T &result) {Result=accumulate (first, last, result); }};template<typename Iterator, TypeName t>T Parallel_accumulate (Iterator First, Iterator last, T init) {unsignedLong ConstLength =std::d istance (first, last);//If there is no element, return init value if(!length) { returnInit; } unsignedLong ConstMin_per_thread = -; //How much threads at least we neededUnsignedLong ConstMax_threads =(Length+ Min_per_thread-1) /Min_per_thread; unsignedLong ConstHardware_threads =std::thread::hardware_concurrency ();//if max_threads more than hardware threads,//just use hardware threads//If hardware threads not even muiltithreads, use 2 threads//instead of, use hardware threadsUnsignedLong ConstNum_threads =Std::min (hardware_threads!=0?hardware_threads:2, max_threads); //The length of the range is divided by threadsUnsignedLong ConstBlock_size = length/num_threads; Std::vector<T>results (num_threads); Std::vector<std::thread> Threads (Num_threads-1); Auto Block_start=First ; for(unsignedLongi =0; I < (num_threads-1); ++i) {Auto Block_end=Block_start; //put Block_end to the end of current blockstd::advance (Block_end, block_size); Threads[i]=Std::thread (Accumulate_block<iterator, t>(), Block_start, Block_end, std::ref(Results[i])); Block_start=Block_end; } Accumulate_block<iterator, t>( ) (Block_start, Last, Results[num_thre Ads-1]); Std::for_each (Threads.begin (), Threads.end (), STD::MEM_FN (&std::thread::join)); returnstd::accumulate (Results.begin (), Results.end (), init);}intmain () {vector<int> ivec{1,2,3,4,5,5,6,7,8,9}; intresult =0; Result=parallel_accumulate (Ivec.cbegin (), ivec.cend (), result); cout<< result <<Endl; return 0;}
Implementing multithreaded versions of accumulate by packaging accumulate