c++++17的execution_policy使用需注意四点:一、选择合适策略,seq用于顺序执行,par允许多线程并行,par_unseq支持并行+向量化;二、任务需满足大数据量、计算密集型才适合并行,小任务反而变慢;三、确保函数无副作用,避免共享变量竞争,可用原子操作或归约算法;四、不同编译器实现有差异,需查文档并做性能测试。

并行算法在C++17中引入了
execution_policy
,让标准库算法支持并行执行。但很多人用的时候容易出错,或者没发挥出性能优势。关键点在于:根据任务特性选择合适的策略,而不是随便加个
par
就完事。

下面几个常见场景和注意事项,帮你正确使用STL的并行策略。

一、了解三种基本执行策略
C++标准提供了三种基础执行策略:
std::execution::seq
:顺序执行,不并行
std::execution::par
:允许并行执行(共享内存线程池)
std::execution::par_unseq
:允许并行+向量化执行(可能跨核+SIMD)
选哪个?看你要处理的任务能不能安全地拆分到多个线程,并且是否能利用SIMD指令加速。

举个例子:
std::vector data = get_big_data();std::sort(std::execution::par, data.begin(), data.end());
这行代码会让排序操作尝试用多线程完成,适用于大数据量、计算密集型任务。
二、别盲目用
par
par
,先判断任务是否值得并行
不是所有算法用了
par
就会变快。小数据量、轻量级操作反而可能因为线程调度开销而变慢。
比如:
std::for_each(std::execution::par, vec.begin(), vec.end(), [](int& x) { x += 1; });
如果vec只有几十个元素,这个并行操作很可能比串行还慢。
建议:
数据量大(比如几万条以上)每个元素的操作较重(比如有函数调用、IO、复杂计算)CPU核心数较多时(4核以上更明显)
才考虑使用
par
或
par_unseq
。
三、注意线程安全和副作用问题
并行算法要求传入的函数对象必须是“无副作用”的,否则行为未定义。
比如下面这个写法就有风险:
int count = 0;std::for_each(std::execution::par, vec.begin(), vec.end(), [&](int x) { if (x > 0) ++count;});
多个线程同时修改
count
变量,没有同步机制,结果不可预测。
解决办法:
使用原子变量(如
std::atomic
)或者改用
transform_reduce
等归约类算法来合并结果
四、不同平台实现差异要留意
虽然C++标准规定了接口,但不同编译器对并行策略的支持程度不一样。
比如:
MSVC 的PPL实现比较早也比较稳定GCC 从9开始支持,但某些算法仍为串行实现Clang支持情况取决于所用的标准库(如libc++或libstdc++)
所以你写的代码在一台机器上跑得飞快,在另一台却没效果,很可能是底层实现的问题。
建议做法:
查阅你使用的编译器文档确认支持情况对关键路径做性能测试不要假设“写了par就一定并行”
基本上就这些。选好策略、控制粒度、注意并发安全,才能真正把并行算法用起来。
以上就是STL并行算法怎么正确使用 execution_policy策略选择指南的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1470854.html
微信扫一扫
支付宝扫一扫