C++并发实战5:并行化的std::accumulate
来源:互联网 发布:绫致淘宝企业店假货 编辑:程序博客网 时间:2024/06/10 09:26
std::thread::hardware_concurrency()可以返回CPU个数,在C++库不能获取CPU信息下可能返回0。该信息是非常有用的,当线程数超过CPU cores会频繁的引起上下文切换,返回会降低性能,当hardware_concurrency()返回0时可以指定一个数目比如2。
下面给出一个并行化的std::accumulate()的例子:std::accumulate(first,last,init,fun)的语义是在一个初始值init前提下将一个[first,last)序列的元素与init执行fun函数。默认fun=NULL是将[first,last)的所有元素加起来再加上init得到序列的累加值。现在并行化:将序列拆分成子序列然后每个子序列的求和由一个线程执行,然后将各个线程的累加值再求和。有点类似于MapReduce的wordcount。
#include<iostream>#include<thread>#include<numeric>#include<algorithm>#include<functional>#include<vector>using namespace std;template<typename Iterator,typename T>struct accumulate_block{ void operator()(Iterator first,Iterator last,T& result){//每个子序列累加,不能通过线程的返回值返回累加结果,而是通过一个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)//若序列为空直接返回init 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();//获取PC的CPU core数目,C++库可能无法访问该信息,所以可能返回0 unsigned long const num_threads=std::min(hardware_threads!=0?hardware_threads:2,max_threads);//最大线程数在计算出来的最大线程数和硬件core数目中取较小者(线程数超过core数目反而降低性能) unsigned long const block_size=length/num_threads;//重新计算每个线程需要执行的序列大小 vector<T> results(num_threads);//每个线程的结果将保存在results中 vector<thread> threads(num_threads-1);//开启线程池,只用开启num_threads-1个子线程,因为主线程也可以计算一个序列 Iterator block_start=first;//序列开始位置 for(int i=0;i<(num_threads-1);i++){//这里只分配子线程的任务序列 Iterator block_end=block_start; std::advance(block_end,block_size);//迭代器block_end向前移动block_size threads[i]=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_threads-1]);//主线程的任务,注意是last std::for_each(threads.begin(),threads.end(),std::mem_fn(&thread::join));//等待子线程完成 return std::accumulate(results.begin(),results.end(),init);//汇总结果}int main(){ vector<int> vec; for(int i=0;i<100;i++){ vec.push_back(10); } int sum=parallel_accumulate(vec.begin(),vec.end(),5); cout<<"sum="<<sum<<endl; return 0;}
程序输出:
sum=1005
- C++并发实战5:并行化的std::accumulate
- std::accumulate异常安全的两个并行版本
- std::transform || inner_product || accumulate
- java并发编程实战-构建高效的并行计算
- std::accumulate(容器求和)
- c++11,std::find的并行化模板化
- C++并发编程实战chapter1你好,C++的并发世界--笔记1--任务并行和数据并行
- 并发 并行的区别
- C++并发实战13:std::future、std::async、std::promise、std::packaged_task
- Java 并发编程实战学习笔记——寻找可强化的并行性
- Java 并发编程实战学习笔记——路径查找类型并行任务的终止
- c++STL之accumulate
- c++ std - accumulate 求数组和
- 并发和并行的区别
- 并发与并行的区别
- 并发和并行的区别
- 并发和并行的区别
- 并发和并行的区别
- 面向过程的程序设计
- worldwind学习笔记-11-下一步咋办?
- 剑指Offer试题总结(二)
- ABAP 图片预览
- Mac常用快捷键一览
- C++并发实战5:并行化的std::accumulate
- IT技术开发论坛大全
- Young矩阵查找(2014美团研发笔试)
- 国储贵金属分析
- hadoop2.2支持snappy压缩安装及配置
- 解决 gcc/g++ 编译动态库通过却无法运行的问题
- Linux Mint下中文输入法的配置
- 基于visual Studio2013解决C语言竞赛题之0510求最大和
- linux下安装mysql时候遇到mysql.sock文件问题