并行版的std::accumulate

2023-12-21 01:52
文章标签 std 并行 accumulate

本文主要是介绍并行版的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。

这篇关于并行版的std::accumulate的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/518282

相关文章

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

Java之并行流(Parallel Stream)使用详解

《Java之并行流(ParallelStream)使用详解》Java并行流(ParallelStream)通过多线程并行处理集合数据,利用Fork/Join框架加速计算,适用于大规模数据集和计算密集... 目录Java并行流(Parallel Stream)1. 核心概念与原理2. 创建并行流的方式3. 适

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

处理List采用并行流处理时,通过ForkJoinPool来控制并行度失控的问题

在使用parallelStream进行处理list时,如不指定线程池,默认的并行度采用cpu核数进行并行,这里采用ForJoinPool来控制,但循环中使用了redis获取key时,出现失控。具体上代码。 @RunWith(SpringRunner.class)@SpringBootTest(classes = Application.class)@Slf4jpublic class Fo

并行编程实战——TBB的安装

一、安装前的准备 在并行编程中,intel TBB还是一个比较强大的框架。可能对大多数数的开发者来说它还是比较陌生的,因为一般很少有公司会直接用到并行框架的水平。比之于OpenMP之类的比较容易直接使用的相关并行库,intel TBB还是一个相对来说比较难的框架。这不光在于开发过程,也因为它的安装过程。 早期的intel TBB安装还是比较复杂的,但随着技术的升级和系统版本的迭代,到现在基本已经

windows C++ 并行编程-使用 加速器 对象(下)

并发运行时支持各种编程模型。 这些模型可能会与其他库的模型重叠或对其进行补充。 本部分中的文档将 OpenMP 与并发运行时进行比较,并提供有关如何迁移现有 OpenMP 代码以使用并发运行时的示例。 OpenMP 编程模型由开放标准定义,具有与 Fortran 和 C/C++ 编程语言定义完善的绑定。 OpenMP 2.0 版和 2.5 版(由 Microsoft C++ 编译器支持)都很适合

【C++学习(28)】通俗一点讲解:std::bind 回调技术

std::bind 是 C++11 标准库中的一个功能,它允许你“绑定”某些参数到一个函数、成员函数或可调用对象上,从而生成一个新的可调用对象。这种新的可调用对象可以稍后被调用,而且其中一些参数已经被预先设置好了。这在回调函数和异步编程中特别有用。 下面我用一个通俗的例子来解释 std::bind 是如何工作的。 假设场景 假设你有一个家庭厨师,他有一个技能叫做“做饭”。做饭需要两个参数:一

Rust模块std::thread

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust到底值不值得学,之一  -CSDN博客 Rust到底值不值得学,之二-CSDN博客 Rust多线程编程概述-CSDN博客 12.3.2  等待所有线程完成 在前面的实例中,主线程没等到派生线程执行完毕就结束了,从而整个进程就会结束