T parallel_accumulate(Iterator first, Iterator last, T init) { unsigned long const length = std::distance(first, last); if (!length) { return init; } unsigned long const block_size = 25; unsigned long const num_blocks = (length + block_size - 1) / block_size; std::vector<std::future<T> > futures(num_blocks - 1); thread_pool pool; Iterator block_start = first; for (unsigned long i = 0; i < (num_threads - 1); ++i) { Iterator block_end = block_start; std::advance(block_end, block_size); futures[i] = pool.submit(accumulate_block<Iterator, T>()); block_start = block_end; } T last_result = accumulate_block()(block_start, last); T result = init; for (unsigned long i = 0; i < (num_blocks - 1); ++i) { result += futures[i].get(); } result += last_result; return result; }
T parallel_accumulate(Iterator first,Iterator last,T init) { unsigned long const length=std::distance(first,last); if(!length) return init; unsigned long const min_per_thread=25; unsigned long const max_threads= (length+min_per_thread-1)/min_per_thread; unsigned long const hardware_threads= std::thread::hardware_concurrency(); unsigned long const num_threads= std::min(hardware_threads!=0?hardware_threads:2,max_threads); unsigned long const block_size=length/num_threads; std::vector<std::future<T> > futures(num_threads-1); std::vector<std::thread> threads(num_threads-1); Iterator block_start=first; for(unsigned long i=0;i<(num_threads-1);++i) { Iterator block_end=block_start; std::advance(block_end,block_size); std::packaged_task<T(Iterator,Iterator)> task( accumulate_block<Iterator,T>()); futures[i]=task.get_future(); threads[i]=std::thread(std::move(task),block_start,block_end); block_start=block_end; } T last_result=accumulate_block()(block_start,last); std::for_each(threads.begin(),threads.end(), std::mem_fn(&std::thread::join)); T result=init; for(unsigned long i=0;i<(num_threads-1);++i) { result+=futures[i].get(); } result += last_result; return result; }