TBB并行编程2 _ 性能测试,任务域

2023-12-02 16:10

本文主要是介绍TBB并行编程2 _ 性能测试,任务域,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

性能测试:

#include <tbb/tick_count.h>
#define TICK(x) auto bench_##x = tbb::tick_count::now();
#define TOCK(x) std::cout << #x ": " << (tbb::tick_count::now() - bench_##x).seconds() << "s" << std::endl;#include <iostream>
#include"ticktock.h"
#include <string>
#include <cmath>
#include <vector>
#include <tbb/parallel_for.h>
#include <tbb/blocked_range.h>
#include <tbb/parallel_reduce.h>void test01() {size_t n = 1 << 27;std::vector<float> a(n);TICK(for);tbb::parallel_for(tbb::blocked_range<size_t>(0, n), [&](tbb::blocked_range<size_t> r) {for (size_t i = r.begin(); i < r.end(); i++) {a[i] = std::sin(i);}});TOCK(for);TICK(reduce);float res = tbb::parallel_reduce(tbb::blocked_range<size_t>(0, n), (float)0, [&](tbb::blocked_range<size_t> r, float local_res) {for (size_t i = r.begin(); i < r.end(); i++) {local_res += a[i];}return local_res; }, [](float x, float y) {return x + y;});TOCK(reduce);std::cout << res << std::endl;
}
void test02() {size_t n = 1 << 27;std::vector<float> a(n);TICK(for);for (size_t i = 0; i < n; i++){a[i] += std::sin(i);}TOCK(for);TICK(reduce);float res = 0;for (size_t i = 0; i < n; i++){res += a[i];}TOCK(reduce);std::cout << res << std::endl;
}int main() {test01();std::cout << "------------" << std::endl;test02();
}

通过上面那个时间戳就可以计时,从结果来看显然并行算法耗时更少。

评价一个并行速度通常会用加速比=串行用时÷并行用时

更专业的性能测试框架:Google benchmark

这个我安装了之后一直显示连接不上。。。。我也很奇怪

#include <iostream>
#include <vector>
#include <cmath>
#include <benchmark/benchmark.h>constexpr size_t n = 1<<27;
std::vector<float> a(n);void BM_for(benchmark::State &bm) {for (auto _: bm) {// fill a with sin(i)for (size_t i = 0; i < a.size(); i++) {a[i] = std::sin(i);}}
}
BENCHMARK(BM_for);void BM_reduce(benchmark::State &bm) {for (auto _: bm) {// calculate sum of afloat res = 0;for (size_t i = 0; i < a.size(); i++) {res += a[i];}benchmark::DoNotOptimize(res);}
}
BENCHMARK(BM_reduce);BENCHMARK_MAIN();

 代码是这样的

回更:安装好啦

 总结安装错误:要找到config。

cmake_minimum_required(VERSION 3.10)set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BUILD_TYPE Release)
SET(TBB_DIR "D:\\vsstl\\C_CUDA\\vcpkg-master\\vcpkg-master\\packages\\tbb_x64-windows\\share\\tbb")
SET(benchmark_DIR "D:\\vsstl\\C_CUDA\\vcpkg-master\\vcpkg-master\\packages\\benchmark_x64-windows\\share\\benchmark")
project(main LANGUAGES CXX)add_executable(main main.cpp)#find_package(OpenMP REQUIRED)
#target_link_libraries(main PUBLIC OpenMP::OpenMP_CXX)find_package(TBB REQUIRED)
target_link_libraries(main PUBLIC TBB::tbb)set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "Turn off the fking test!")
find_package(benchmark CONFIG REQUIRED)
target_link_libraries(main PUBLIC benchmark::benchmark benchmark::benchmark_main)

任务域与嵌套

#include <iostream>
#include <tbb/parallel_for.h>
#include <tbb/task_arena.h>
#include <vector>
#include <cmath>int main() {size_t n = 1<<26;std::vector<float> a(n);tbb::task_arena ta(4);//可以指定用多少线程ta.execute([&] {tbb::parallel_for((size_t)0, (size_t)n, [&] (size_t i) {a[i] = std::sin(i);});});return 0;
}

也可以用两个for进行嵌套,这样可以解决n比较小,核心没有用光的问题:

tbb::parallel_for((size_t)0, (size_t)n, [&] (size_t i) {tbb::parallel_for((size_t)0, (size_t)n, [&] (size_t j) {a[i * n + j] = std::sin(i) * std::sin(j);});});

但是嵌套会导致死锁问题:

tbb::parallel_for((size_t)0, (size_t)n, [&] (size_t i) {std::lock_guard lck(mtx);tbb::parallel_for((size_t)0, (size_t)n, [&] (size_t j) {a[i * n + j] = std::sin(i) * std::sin(j);});});

这是因为tbb采用的是工作窃取法,就是在线程t1做完自己的工作之后,就会去看别的线程有没有做完工作,如果还有没做完的工作就会从这个线程里将工作取出,放到自己的t1线程里。

因此内部 for 循环有可能“窃取”到另一个外部 for 循环的任务,从而导致 mutex 被重复上锁。

所以为了解决这种问题:

1、用递归锁:

std::recursive_mutex mtx;

2、另外创建一个任务域

 tbb::parallel_for((size_t)0, (size_t)n, [&] (size_t i) {std::lock_guard lck(mtx);tbb::task_arena ta;ta.execute([&] {tbb::parallel_for((size_t)0, (size_t)n, [&] (size_t j) {a[i * n + j] = std::sin(i) * std::sin(j);});});});

3、isolate隔离:

tbb::parallel_for((size_t)0, (size_t)n, [&] (size_t i) {std::lock_guard lck(mtx);tbb::this_task_arena::isolate([&] {tbb::parallel_for((size_t)0, (size_t)n, [&] (size_t j) {a[i * n + j] = std::sin(i) * std::sin(j);});});});

这篇关于TBB并行编程2 _ 性能测试,任务域的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

黑神话,XSKY 星飞全闪单卷性能突破310万

当下,云计算仍然是企业主要的基础架构,随着关键业务的逐步虚拟化和云化,对于块存储的性能要求也日益提高。企业对于低延迟、高稳定性的存储解决方案的需求日益迫切。为了满足这些日益增长的 IO 密集型应用场景,众多云服务提供商正在不断推陈出新,推出具有更低时延和更高 IOPS 性能的云硬盘产品。 8 月 22 日 2024 DTCC 大会上(第十五届中国数据库技术大会),XSKY星辰天合正式公布了基于星

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。