std::thread::hardware_concurrency()在C++標準庫中,這個函數(shù)將返回能同時并發(fā)在一個程序中的線程數(shù)量。
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)
{
//輸入范圍,length
unsigned long long length = std::distance(first, last);
if (!length) //1
return init;
unsigned long const min_per_thread = 25;
//確定啟動線程的最大數(shù)量
unsigned long const max_threads =
(length + min_per_thread - 1) / min_per_thread; //2
unsigned long const hardware_threads =
std::thread::hardware_concurrency();
//啟動線程數(shù)量的確定
unsigned long const num_threads = //3
std::min(hardware_threads != 0 ? hardware_threads : max_threads);
//每個線程中的元素數(shù)量
unsigned long const block_size = length / num_threads; //4
std::vector<T> results(num_threads);
//啟動的線程數(shù)必須必num_threads少1個,因為在啟動之前已經(jīng)有一個主線程了。
std::vector<std::thread> threads(num_threads - 1);//5
Iterator block_start = first;
for (unsigned long i = 0; i < (num_threads - 1); ++i)
{
Iterator block_end = block_start;
//block_end指向當前塊的末尾
std::advance(block_end, block_size);//6
//啟動一個新線程為當前塊累加結(jié)果
threads[i] = std::thread( //7
accumulate_block<Iterator, T>(),
block_start, block_end, std::ref(results[i]));
//當?shù)髦赶虍斍皦K的末尾時震糖,啟動下一塊
block_start = block_end; //8
}
//處理最終塊的結(jié)果
accumulate_block<Iterator, T>()(
block_start, last, results[num_threads - 1]); //9
std::for_each(threads.begin(), threads.end(),
std::mem_fn(&std::thread::join)); //10
return std::accumulate(results.begin(), results.end(), init); //11
}
啟動線程數(shù)量的確定,計算量的最大值和硬件支持線程數(shù)中較小的值為啟動線程數(shù)量趴腋。
mem_fn
mem_fn里面的mem就是指類的成員member, 而fn就是指function, 加在一起就是說member function吊说,即mem_fn是用來適配類的成員函數(shù)的。把成員函數(shù)轉(zhuǎn)為函數(shù)對象优炬,使用對象指針或?qū)ο?引用)進行綁定颁井。