当前位置: 首页 > news >正文

tbb parallel_for 使用

tbb parallel_for 的接口

tbb parallel_for主要用于并发的执行任务,对于tbb的接口函数如下所示:

//! Parallel iteration over a range of integers with a step provided and simple partitioner
template <typename Index, typename Function>
void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& partitioner) {parallel_for_impl<Index,Function,const simple_partitioner>(first, last, step, f, partitioner);
}

也就是它就接受的参数,就是迭代器的first和last以及这个步长信息,如果没有给步长信息的话,默认的话会调用下面的接口,也就是步长默认是1.

//! Parallel iteration over a range of integers with a default step value and default partitioner
template <typename Index, typename Function>
void parallel_for(Index first, Index last, const Function& f) {parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, auto_partitioner());
}

而在我们的实际开发中使用tbb::parellel_for的时候其实主要有两种情况。

例子

我想求0-9 10个数的平方,如果我们正常的写法的话,我们直接一个for循环就能搞定了,因为每次计算都比较省时间,但是如果不是求一个数的平方,而是其它复杂的计算逻辑,那么这个计算量可能就比较的大了,而我们如果用for循环,就没有办法充分利用我们多个核心的优势,导致是串行计算。

我们如果想计算每个数据,然后把数据放在一个结构中存储起来,就是涉及到读写的问题,那么如果引入了tbb一定要保证线程的安全,如果线程不安全就没有办法保证并行了。

然后针对两种不同情况给出不同的代码写法:

1.我们并行操作的数据比如vector,数组的长度是固定的,不需要动态的扩容

我么就可以用tbb直接并行了,代码如下:

#include <iostream>
#include <vector>
#include <tbb/parallel_for.h>
#include <tbb/global_control.h>int main() {tbb::global_control gc(tbb::global_control::max_allowed_parallelism, 10);const int N = 10;std::vector<int> numbers(N);for (int i = 0; i < N; ++i) {numbers[i] = i;}// 关键改动:预分配固定大小,每个元素位置独立std::vector<std::pair<int, unsigned long>> results(N);  // 直接初始化大小为Ntbb::parallel_for(0, N, 1,[&](int i) {int num = numbers[i];results[i] = {num, num * num};  // 直接通过索引写入,无竞争!});// 打印结果(顺序固定)for (const auto& [num, square] : results) {std::cout << num << "^2 = " << square << std::endl;}return 0;
}

tbb的源码我已经安装到我的机器上了,这个大家如果没有安装,可以自行参考 tbb官网进行安装。

编译代码:

g++ -std=c++17 tbb_parallel_for.cpp -I /opt/voy-sdk/include/ -L /opt/voy-sdk/lib  -o test -ltbb

执行代码:

./test

代码的输出结果如下:

0^2 = 0
1^2 = 1
2^2 = 4
3^2 = 9
4^2 = 16
5^2 = 25
6^2 = 36
7^2 = 49
8^2 = 64
9^2 = 81

2.我们并行操作的数据比如vector,数组的长度不是固定的,需要动态扩容,我们不确定大小

这个时候如果想要保证写入的安全性,就需要我们用到tbb提供的安全容器。

#include <iostream>
#include <vector>
#include <tbb/parallel_for.h>
#include <tbb/concurrent_vector.h>
#include <tbb/global_control.h>int main() {tbb::global_control gc(tbb::global_control::max_allowed_parallelism, 10);const int N = 10;std::vector<int> numbers(N);for (int i = 0; i < N; ++i) {numbers[i] = i;}tbb::concurrent_vector<std::pair<int, unsigned long>> results;// 步长=1,每个i对应一个元素tbb::parallel_for(0, N, 1,  // 关键改动:步长=1[&](int i) {int num = numbers[i];results.push_back({num, num * num});  // 直接处理单个元素});// 打印结果for (const auto& [num, square] : results) {std::cout << num << "^2 = " << square << std::endl;}return 0;
}

相关文章:

  • 颜色分类,不靠“调色盘”:双指针 VS 计数排序的正面PK
  • 【Linux】服务自启动设置的方式
  • LayerSkip: Enabling Early Exit Inference and Self-Speculative Decoding
  • Java之BigDecimal
  • Silvaco仿真中victory process的蒙特卡洛(Monte Carlo)离子注入
  • 深入理解 Linux 权限管理:从基础到进阶
  • 【GESP】C++三级练习 luogu-B2117 整理药名
  • (三十二)Android开发中AppCompatActivity和Activity之间的详细区别
  • 2025运维工程师面试题1(答案在后一张)
  • 企业的AI转型:生死时速的进化之路
  • 【题解-Acwing】870. 约数个数
  • k8s部署
  • 4.29【Q】paraCompute
  • python之数字类型的操作
  • 无人机航拍羊只检测数据集VOC+YOLO格式6065张1类别
  • vue3使用<el-date-picker分别设置开始时间和结束时间时,设置开始时间晚于当前时间,开始时间早于结束时间,结束时间晚于开始时间
  • python:练习:2
  • 双重差分模型学习笔记(理论)
  • YOLO学习笔记 | YOLOv8与卡尔曼滤波实现目标跟踪与预测(附代码)
  • 【CF】Day46——Codeforces Round 967 (Div. 2) B
  • 中央网信办:重点整治违规AI产品、利用AI制作发布谣言等突出问题
  • 关于新冠疫情防控与病毒溯源的中方行动和立场
  • 中国人保一季度业绩“分化”:财险净利增超92%,寿险增收不增利
  • 深入贯彻中央八项规定精神学习教育中央指导组派驻地方和单位名单公布
  • 五月院线片单:就看五一档表现了
  • 总书记考察的上海“模速空间”,是一个怎样的空间?