并行版的std::accumulate

代码来自C++并发编程实战 

#include <iostream>
#include <thread>
#include<functional>
#include <algorithm>
#include <vector>
#include <numeric>//标准库里的accumulate在这个头文件里
using namespace std;
using namespace placeholders;
template<typename Iterator,typename T>
struct accumulage_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) {
    unsigned long const length = distance(first, last);//获得两个迭代器之间的距离
    if (!length)//长度为0,直接返回
        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 = thread::hardware_concurrency();
    unsigned long const num_threads=min(hardware_threads!=0?hardware_threads:2, max_threads);//上面的是在决定线程数量
    unsigned long const block_size = length / num_threads;//根据线程数量把范围内的元素分块,每个线程处理对应块范围块的累加
    vector<T> results(num_threads);//每个线程对应的块范围的累加结果,存在这里
    vector<thread> threads(num_threads - 1);//线程数量-1,因为这里是主线程还算一个
    Iterator block_start = first;
    for (unsigned long i = 0; i < num_threads - 1; i++) {
        Iterator block_end = block_start;
        advance(block_end, block_size);//每次尾迭代器移动一个块的大小
        threads[i] = thread(accumulage_block<Iterator, T>(), block_start, block_end, ref(results[i]));//创建一个线程,计算一个块范围内的累加和
        block_start = block_end;//首迭代器移动,使得bolck_start和block_end始终相差一个块的距离
    }
    accumulage_block<Iterator, T>()(block_start, last, results[num_threads - 1]);//主线程处理 最后一块
    for_each(threads.begin(), threads.end(), mem_fn(&thread::join));//等待所有线程结束
    return accumulate(results.begin(), results.end(), init);//把每个线程的结果累加
}
int main()
{
    vector<int> vec{ 1,4,5,6,3,2 };
    int ans = parallel_accumulate<vector<int>::iterator,int>(vec.begin(),vec.end(), 0);
    cout << ans;
    
}

std::thread::hardware_concurrency 是 C++ 标准库中的一个函数,用于获取计算机硬件支持的并发线程数目。这个函数返回一个 unsigned int 类型的值,表示硬件支持的并发线程数,如果无法检测则返回 0。

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值