C++17并行化加速STL算法——std::execution
C++17 并行化STL算法
文章目录
- C++17 并行化STL算法
- 概念
- 环境准备
- 工具类
- 并行算法 - 使用
- 并行算法 - 执行策略
- 总览
- 选择标准
- 详细介绍
- 顺序执行 seq
- 并行化顺序执行 par
- 并行化乱序执行 par_unseq
- 并行算法 - 异常处理
- 可以不使用并行算法
- 并行算法 - 限制
- 并行算法有哪些
- 原有算法
- 17引入新算法
概念
为了从现代的多核体系中受益,C++17标准库引入了并行 STL算法,允许使用多个线程并行处理元素。
C++17为许多算法扩展了一个新的参数来指明是否要并行运行算法。并且新增了一些专为并行编程补充的新算法。
环境准备
并行算法在 linux上使用 gcc 或者 clang进行编译,需要
- 安装
tbb库—— 线程构建模块 (TBB) Thread Building Blocks - 链接时指定
-ltbb选项
否则:
tbb库 | 链接 | 结果 |
|---|---|---|
| 安装 | 指定-ltbb选项 | 可正常使用并行算法 |
| 安装 | 未指定 | 编译错误 |
| 未安装 | 指定 | 编译错误 |
| 未安装 | 未指定 | 正常编译,但并行算法会串行化,变得和串行算法一样 |
# 编译选项
g++ ‐std=c++17 ‐ltbb main.cpp ‐o a.out
工具类
有时需要计时器来测量算法的速度。因此,引入一个简单的辅助类。
初始化一个计时器,提供 printDiff()来打印出消耗的毫秒数 并 重新初始化计时器
#include <iostream>
#include <string>
#include <chrono>
/********************************************
* timer to print elapsed time
********************************************/
class Timer {
private:std::chrono::steady_clock::time_point last;
public:Timer() : last{std::chrono::steady_clock::now()} {}void printDiff(const std::string& msg = "Timer diff: ") {auto now{std::chrono::steady_clock::now()};std::chrono::duration<double, std::milli> diff{now ‐ last};std::cout << msg << diff.count() << "ms\n";last = std::chrono::steady_clock::now();}
};
并行算法 - 使用
怎么让现有算法并行运行和使用新的并行算法
- 包含头文件
<execution>
#include <execution>
-
C++17之后,一般来说可以向并行 STL算法传递不同的
执行策略 (execution policies)作为第一个参数。-
cpprefrence上看看STL算法支不支持,一般是:添加执行策略到第一个参数即可。例如,
std::execution::par) -
使用参数
传递/修改 执行策略的好处:可在运行时更改策略时(顺序执行/并行执行),不需要再修改调用方式。
-
所有的并行算法要求迭代器至少是前向迭代器。
#include <execution> // for 执行策略
#include <algorithm>std::vector<std::string> coll {"a", "b", "c"};sort(coll.begin(), coll.end());
sort(std::execution::seq, coll.begin(), coll.end());
sort(std::execution::par, coll.begin(), coll.end());
sort(std::execution::par_unseq, coll.begin(), coll.end());// 并行计算平方根
for_each(std::execution::par,coll.begin(), coll.end(),[] (auto& val) {val.sqrt = std::sqrt(val.value);});
并行算法 - 执行策略
总览
以下执行策略,分别是定义在
namespace std中的新类(sequenced_policy、parallel_policy、parallel_unsequenced_policy)的 constexpr对象。
| 执行策略 | 含义 |
|---|---|
std::execution::seq | 顺序执行 |
std::execution::par | 并行化顺序执行 |
std::execution::par_unseq | 并行化乱序(矢量化)执行 |
标准库提供了新的类型特征 std::is_execution_policy<>,在泛型编程中检查模板参数是否是执行策略。
并行化乱序执行需要编译器/硬件的特殊支持,从而检测如何矢量化。
非并行化/并行化
- 并行化——多个线程执行
- 非并行化——单一线程
顺序、乱序
-
乱序:允许矢量化执行,不保证顺序地对元素执行操作。
即存在可能:
-
某个线程在执行完某一个元素的处理之前可能会切换到其他的元素。
-
某个线程先执行多个元素的第一步处理,再回过头来对这些元素执行下一步处理。
-
-
顺序:不允许矢量化执行,顺序地对元素执行操作
当某个线程对新的元素进行操作之前,它会先处理完它之前处理过的其他元素。
选择标准
benchmark测试结果,主要依赖于硬件、使用的 C++编译器、使用的 C++库(并行算法实际运行的方式是实现特定的)
没有通用的方法来判断什么场景什么时间值得使用并行算法。不能说多线程就一定比顺序执行好:启动和控制多线程也会消耗时间。
从理论上讲,如下判断依据可以作为参考:
-
简单算法(每个元素计算耗时短),元素数量少。并行执行永远会更慢建议顺序执行
std::execution::seq或 默认版本。 -
复杂算法(每个元素计算耗时长),元素数量多。适合使用并行算法
- 处理过程需要独立于其他元素的处理 —— 并行化顺序执行
std::execution::par - 处理过程不需要独立于其他元素的处理 —— 并行化乱序执行
std::execution::par_unseq
- 处理过程需要独立于其他元素的处理 —— 并行化顺序执行
详细介绍
顺序执行 seq
std::execution::seq 指定顺序执行
-
策略本身:
- 单一线程执行
- 单个线程对所有元素逐个执行操作。不允许矢量化执行,顺序地对元素执行操作——当某个线程对新的元素进行操作之前,它会先处理完它之前处理过的其他元素。
-
与非并行化版本进行对比
- 实际上,该策略非常类似不接受执行策略参数的非并行化版本
- 但多一些约束条件:例如 for_each()不能返回值,所有的迭代器必须至少是前向迭代器
-
提供该策略的目的:
- 可只修改一个参数来要求顺序执行,而不是换用一个签名不同的函数。
并行化顺序执行 par
std::execution::par 指定并行化顺序执行
-
策略本身:
- 多个线程执行
- 顺序执行:允许矢量化
-
提供该策略的目的:
-
比非并行化顺序执行,可能要快一些
-
避免在以下情况中出现死锁或其它bug(与 par_unseq不同)
执行了某个元素的第一步处理后必须在执行另一个元素的第一步处理之前执行这个元素接下来的处理步骤。
-
并行化乱序执行 par_unseq
std::execution::par_unseq 指定并行化乱序执行
- 策略本身:
- 多个线程执行
- 乱序执行:允许矢量化
- 提供该策略的目的:
- 比非矢量化 顺序执行,可能要快一些
并行化乱序执行需要编译器/硬件的特殊支持来检测哪些操作如何矢量化。
并行算法 - 异常处理
当指定了执行策略后:
-
处理元素的函数,因未捕获的异常而退出时,会调用
std::terminate() -
注意即使选择了顺序执行策略也会这样。
注意:存在并行算法本身抛出异常的可能性!
例如,申请并行执行所需的临时内存资源时失败了,会抛出
std::bad_alloc异常。从而直接std::terminate()
所以,使用非并行化版本的算法有时是更好的选择。
可以不使用并行算法
使用非并行算法可以提供以下好处:
- 可以使用输入和输出迭代器。
- 算法不会在遇到异常时
std::terminate() - 算法可以避免因为意外使用元素导致的副作用。
- 算法可以提供额外的功能,例如 for_each()会返回传入的可调用对象,我们可能会需要该对象最终的状态
并行算法 - 限制
有限制的并行 STL算法
限制:返回类型 void、前向迭代器
for_each()
限制:前向迭代器
for_each_n() all_of(), and_of(), none_of()
find(), find_if(), find_if_not()
find_first_of()
count(), count_if()
mismatch()
equal()
is_partitioned()
partial_sort_copy()
includes()
lexicographical_compare()
fill_n()
generate_n()
reverse_copy()
rotate_copy()
copy(), copy_n(), copy_if()
move()
transform()
replace_copy(), replace_copy_if()
remove_copy(), remove_copy_if()
unique_copy()
partition_copy()
merge()
set_union(), set_intersection()
set_differrnce(), set_symmetric_difference()
inclusive_scan(), exclusive_scan()
transform_inclusive_scan(), transform_exclusive_scan()
并行算法有哪些
原有算法
C++17之前,标准中不需要修改就可以并行运行的算法
find_end(), adjacent_find()
search(), search_n()(和“搜索器”一起使用时除外)
swap_ranges()
replace(), replace_if()
fill()
generate()
remove(), remove_if(), unique()
reverse(), rotate()
partition(), stable_partition()
sort(), stable_sort(), partial_sort()
is_sorted(), is_sorted_until()
nth_element()
inplace_merge()
is_heap(), is_heap_until()
min_element(), max_element(), min_max_element()
无并行版本的算法
- 为了并行地运行 accumulate(),使用reduce() 或者transform_reduce()。
- 为了并行地运行 partial_sum(),使用…scan()算法。
- 为了并行地运行 inner_product(),使用transform_reduce()。
accumulate()
partial_sum()
inner_product()
search()(和“搜索器”一起使用时)
copy_backward(), move_backward()
sample(), shuffle()
partition_point()
lower_bound(), upper_bound(), equal_range()
binary_search()
is_permutation()
next_permutation(), prev_permutation()
push_heap(), pop_heap(), make_heap(), sort_heap()
17引入新算法
相关文章:
C++17并行化加速STL算法——std::execution
C17 并行化STL算法 文章目录 C17 并行化STL算法概念环境准备工具类 并行算法 - 使用并行算法 - 执行策略总览选择标准详细介绍顺序执行 seq并行化顺序执行 par并行化乱序执行 par_unseq 并行算法 - 异常处理可以不使用并行算法并行算法 - 限制并行算法有哪些原有算法17引入新算…...
从sumsub获取用户图片
已经拿到了imageid 然后从哪个接口可以获取图片文件呢? 根据您的问题,我可以为您提供以下信息: 一旦您获得了imageId,您可以使用以下几个API接口来获取图片文件: 获取文档图片: Get document images GET https://api.sumsub.com/resources/inspections/{inspection…...
DeepSeek + Mermaid编辑器——常规绘图
下面这张图出自:由清华大学出品的 《DeepSeek:从入门到精通》。 作为纯文本生成模型,DeepSeek虽不具备多媒体内容生成接口,但其开放式架构允许通过API接口与图像合成引擎、数据可视化工具等第三方系统进行协同工作,最终…...
ARM64 Trust Firmware [五 ]
本章介绍 ATF 中的 Runtime Service 是如何定义和被调用的。 要了解 SMC,必须从 SMC 指令本身开始,其指令如下图: 指令格式为:SMC #<imm>,从官方文档了解到该指令只能在 EL1 以及更高的异常等级上调用ÿ…...
Excel核心函数VLOOKUP全解析:从入门到精通
一、函数概述 VLOOKUP是Excel中最重要且使用频率最高的查找函数之一,全称为Vertical Lookup(垂直查找)。该函数主要用于在数据表的首列查找特定值,并返回该行中指定列的对应值。根据微软官方统计,超过80%的Excel用户在…...
KTransformers如何通过内核级优化、多GPU并行策略和稀疏注意力等技术显著加速大语言模型的推理速度?
KTransformers通过内核级优化、多GPU并行策略和稀疏注意力等技术显著加速大语言模型的推理速度,具体体现在以下几个方面: 内核级优化: KTransformers采用了高效的内核级优化技术,包括对Transformer模型中的关键操作进行优化。例如…...
审计级别未启用扩展模式导致查询 DBA_AUDIT_TRAIL 时 SQL_TEXT 列为空
如果查询 DBA_AUDIT_TRAIL 时发现 SQL_TEXT 列为空,但其他字段(如 OS_USERNAME、USERNAME、TIMESTAMP 等)有数据,可能是由于以下原因之一。以下是可能的原因及解决方法: 1. 审计级别未启用扩展模式 默认情况下&#x…...
微信小程序项目 video 组件失效问题,无法播放本地视频
问题与处理策略 问题描述 <video src"../../assets/video/test-video.mp4" controls style"width: 100%; height: 300px;"></video>在微信小程序项目中,上述 video 组件失效,视频无法加载,无法播放本地视频…...
若依-@Excel新增注解numberFormat
Excel注解中原本的scale会四舍五入小数,导致进度丢失 想要的效果 显示的时候保留两个小数真正的数值是保留之前的数值 还原过程 若以中有一個專門的工具类,用来处理excel的 找到EXCEL导出方法exportExcel()找到writeSheet,写表格的方法找到填充数据的方法…...
网络安全行业有哪些公司
只是简单做一下网络安全公司梳理,不作点评,下列排名不分先后。 一、常见的网络安全公司 1、天融信 天融信(002212.SZ)创始于1995年,是上市公司中成立最早的网络安全企业,亲历中国网络安全产业的发展历程…...
存储区域网络(SAN)管理
存储区域网络(Storage Area Network,SAN)采用网状通道(Fibre Channel ,简称FC)技术,通过FC交换机连接存储阵列和服务器主机,建立专用于数据存储的区域网络。SAN提供了一种与现有LAN连…...
如何使用Spark SQL进行复杂的数据查询和分析
使用Spark SQL进行复杂的数据查询和分析是一个涉及多个步骤和技术的过程。以下是如何使用Spark SQL进行复杂数据查询和分析的详细指南: 一、准备阶段 环境搭建: 确保已经安装并配置好了Apache Spark环境。准备好数据源,可以是CSV文件、JSON…...
sass报错:[sass] Undefined variable. @import升级@use语法注意事项
今天创建vue3项目,迁移老项目代码,使用sass的时候发现import语法已经废弃,官方推荐使用use替换。 这里我踩了一个坑找半天的问题,原因是sass升级到1.85之后 定义变量前加上 - 就是表示变量私有,即使使用use导出 在新的…...
使用 SDKMAN! 在 Mac(包括 ARM 架构的 M1/M2 芯片)安装适配 Java 8 的 Maven
文章目录 1、安装 SDKMAN!2、安装 Maven:2.1、maven 3.9.62.2、maven 3.8.1 好的,这是使用 SDKMAN! 安装适配 Java 8 的 Maven 的步骤: 1、安装 SDKMAN! 前提条件: 安装 SDKMAN!: 如果你的系统上没有安装 SDKMAN!,请按照以下说明进行安装: c…...
anythingllm服务器部署+ollama+deepseek+实现本地知识库问答
一、docker安装anythingllm 1、拉取镜像 docker pull mintplexlabs/anythingllm:latest 2、创建db目录和配置文件并运行 anythingLLM 容器 export STORAGE_LOCATION/data/ai/wjh_team/anythingllm && \mkdir -p $STORAGE_LOCATION && \touch "$STORAG…...
深度学习04 数据增强、调整学习率
目录 数据增强 常用的数据增强方法 调整学习率 学习率 调整学习率 调整学习率的方法 有序调整 等间隔调整 多间隔调整 指数衰减 余弦退火 自适应调整 自定义调整 数据增强 数据增强是通过对训练数据进行各种变换(如旋转、翻转、裁剪等)&am…...
2023年全国职业院校技能大赛GZ073网络系统管理赛项赛题第10套模块A:网络构建
有问题请留言或主页私信咨询 2023年全国职业院校技能大赛 GZ073网络系统管理赛项 赛题第10套 模块A:网络构建 **目 **录 任务清单 (一)基础配置 (二)有线网络配置 (三)无线…...
2023年河北省职业院校技能大赛网络系统管理赛项样题解法
有问题请留言或主页私信咨询 配置文件有部分测试时的冗余配置无视即可。 解法只有大致解法,并不完整。请参考配置,自己补全 基础配置 1.所有交换机和无线控制器开启SSH服务,用户名密码分别为admin、admin1234;密码为明文类…...
vite+vue3开发uni-app时低版本浏览器不支持es6语法的问题排坑笔记
重要提示:请首先完整阅读完文章内容后再操作,以免不必要的时间浪费!切记!!!在使用vitevue3开发uni-app项目时,存在低版本浏览器不兼容es6语法的问题,如“?.” “??” 等。为了方便…...
Linux系统编程基础详解
Linux 系统详解 大纲 引言 Linux 的定义Linux 的历史与发展本文结构概述 Linux 的基本概念 Linux 的架构 内核与用户空间系统调用 Linux 的文件系统 文件与目录结构权限管理 Linux 的进程管理 进程与线程进程调度 Linux 的基本命令与操作 常用命令概述 文件与目录操作命令文…...
终极泰拉瑞亚模组指南:如何用tModLoader打造你的专属游戏世界
终极泰拉瑞亚模组指南:如何用tModLoader打造你的专属游戏世界 【免费下载链接】tModLoader A mod to make and play Terraria mods. Supports Terraria 1.4 (and earlier) installations 项目地址: https://gitcode.com/gh_mirrors/tm/tModLoader 你是否厌倦…...
Android 广告 SDK 接入避坑指南:从入门到收益翻倍
一、为什么写这篇做了 5 年 Android 广告 SDK 开发,先后接入了穿山甲(Pangle)、优量汇(腾讯广点通)、快手广告、百度联盟、Sigmob、TopOn 聚合等 10 广告平台和聚合平台。踩过内存泄漏的坑、ANR 的坑、审核被拒的坑、收…...
FPGA实现USB-CDC虚拟串口:轻量级Verilog模块设计与应用
1. 项目概述:一个轻量级的USB-CDC Verilog实现如果你玩过TinyFPGA或者Fomu这类小尺寸的FPGA开发板,大概率会为如何与PC进行高速、稳定的数据通信而头疼。传统的UART串口速度慢,而像SPI、I2C这类协议又需要额外的USB转接芯片,增加了…...
Phi-3.5-mini-instruct算法解析实战:图解经典网络与PID控制原理
Phi-3.5-mini-instruct算法解析实战:图解经典网络与PID控制原理 1. 模型能力概览 Phi-3.5-mini-instruct作为一款专注于技术解析的轻量级模型,其核心优势在于将复杂的算法原理转化为工程师能快速理解的直观解释。不同于传统教材的数学推导,…...
Phi-3.5-mini-instruct应用场景:自媒体内容润色、周报提炼、技术博客辅助写作
Phi-3.5-mini-instruct应用场景:自媒体内容润色、周报提炼、技术博客辅助写作 1. 模型简介 Phi-3.5-mini-instruct是一款轻量级但功能强大的中文文本生成模型,特别适合需要高效处理文本内容的场景。这个模型已经完成了网页封装,用户无需编写…...
科目一通关攻略
本节内容是科目一速通攻略,欢迎各位同学学习,在学习过程中,可以参考下面的视频,祝愿同学们都可以取得满分! 视频资料:https://www.bilibili.com/video/BV1Vj411t7ri?spm_id_from333.788.videopod.episode…...
如何免费解锁原神60帧限制:终极FPS解锁器完全指南
如何免费解锁原神60帧限制:终极FPS解锁器完全指南 【免费下载链接】genshin-fps-unlock unlocks the 60 fps cap 项目地址: https://gitcode.com/gh_mirrors/ge/genshin-fps-unlock 你是否厌倦了原神游戏中被锁定的60帧限制?想要体验更流畅的144H…...
当“伪造借书证”遇上现代API密钥管理:从一篇课文聊聊身份认证与访问控制的安全演进
从借书证到API密钥:身份认证技术的百年安全进化史 二十世纪初的美国南方,一位黑人青年用伪造的借书证叩开了知识的大门;百年后的数字世界,开发者们用API密钥访问云端资源。两种看似迥异的场景,却揭示了相同的安全命题&…...
38程序员转行大模型,2个月零基础转行大模型,成功拿下月薪2w+的offer!我的亲身经历分享
作为一位30北漂男程序员,2个月零基础转行大模型,成功拿下月薪2w的offer!今天我来分享一下我的亲身经历, 希望能给还在迷茫中的你一些启发!转行前的“悲惨”生活 我,一个30男单身青年,因为家里在…...
BiCLIP:结构化几何变换在跨模态检索中的应用与优化
1. 项目背景与核心价值去年在做跨模态检索项目时,我深刻体会到图像和文本对齐的痛点——传统方法要么过度依赖全局特征丢失细节,要么陷入局部匹配缺乏整体一致性。直到看到BiCLIP这篇论文,才发现结构化几何变换这个思路如此精妙。它不像常规对…...
