在运行时选择线程数量:std::thread:hardware_currency()
,这个函数返回一个对于给定程序执行时能够真正并发运行的线程数量的指示,如果该信息不可用则函数会返回0。例如,在多核系统上它可能是CPU核心的数量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| template<typename Iterator, typename T> struct accumulate_block { void operator()(Iterator first, Iterator last, T&result) { result = std::accumulate(first, last, result); } };
template<typename Iterator, typename T> 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_thread = (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<T> results(num_threads); 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); threads[i] = std::thread(accumulate_block<Iterator, T>(), block_start, block_end, std::ref(results[i])); block_start = block_end; } accumulate_block<Iterator, T>()(start, last, results[num_threads - 1]); std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join)); return std::accumulate(results.begin(), results.end(); init); }
|