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

(C++17) std算法之执行策略 execution

文章目录

  • 前言
  • Code测试
    • Code
    • 运行效果
  • msvc源码描述
    • 源码
    • std::sequenced_policy seq
    • std::parallel_policy par
    • std::parallel_unsequenced_policy par_unseq
    • std::unsequenced_policy unseq
  • END

前言

ref:算法库-执行策略 - cppreference.com

利用多核cpu加速算法在目前看来已经不是什么新鲜事了。在C++17中,推出了算法函数的执行策略,可以选择执行策略来优化算法的执行效果。(注意不是所有算法都支持)

目前到C++20,已经支持了四种执行策略。当然本文也仅仅是做简单的展示和描述,因此内部细节十分复杂不是几篇端文章就能看懂的。

标准策略执行策略类型(类)全局执行策略对象(常量)
C++17串行执行sequenced_policystd::execution::seq
C++17并行执行parallel_policystd::execution::par
C++17并行无序执行parallel_unsequenced_policystd::execution::par_unseq
C++20无序执行unsequenced_policystd::execution::unseq
功能特性测试标准功能特性
__cpp_lib_parallel_algorithm201603LC++17并行算法
__cpp_lib_execution201603LC++17执行策略
__cpp_lib_execution201902LC++20std::execution::unsequenced_policy

Code测试

Code

这里仅展示一个比较简单的小例子,仅做小参考。

#include <algorithm>
#include <ctime>
#include <execution>
#include <iostream>
#include <string>
#include <vector>/*** 辅助计时类*/
class Timer {std::string str;clock_t     start;public:Timer(const std::string& str) : str(str) {start = clock();}~Timer() {clock_t end = clock();std::cout << str << " => " << (end - start) / 1000.0 << '\n';}
};/*** 串行执行策略* class sequenced_policy;*/
void test_sequenced_policy(std::vector<int> arr) {Timer timer("std::execution::seq");std::sort(std::execution::seq, arr.begin(), arr.end());
}/*** 并行执行策略* class parallel_policy;*/
void test_parallel_policy(std::vector<int> arr) {Timer timer("std::execution::par");std::sort(std::execution::par, arr.begin(), arr.end());
}/*** 并行无序执行策略* class parallel_unsequenced_policy;*/
void test_parallel_unsequenced_policy(std::vector<int> arr) {Timer timer("std::execution::par_unseq");std::sort(std::execution::par_unseq, arr.begin(), arr.end());
}/*** 无序执行策略* class unsequenced_policy;*/
void test_unsequenced_policy(std::vector<int> arr) {
#if __cpp_lib_execution >= 201902LTimer timer("std::execution::unseq");std::sort(std::execution::unseq, arr.begin(), arr.end());
#endif
}int main() {// help datastd::vector<int> arr;for (int i = 0; i < 3.0 * 100'000'00; i += 1) {arr.push_back(rand());}test_sequenced_policy(arr);test_parallel_policy(arr);test_parallel_unsequenced_policy(arr);test_unsequenced_policy(arr);
}

运行效果

使用编译器:vs2019 => _MSC_VER = 1929

这只是基于笔者本地的单词测试,仅作参考。

x86-Debug

std::execution::seq => 22.874
std::execution::par => 5.495
std::execution::par_unseq => 5.854
std::execution::unseq => 22.864

x86-Release

std::execution::seq => 1.249
std::execution::par => 0.258
std::execution::par_unseq => 0.253
std::execution::unseq => 1.201

x64-Debug

std::execution::seq => 8.705
std::execution::par => 2.371
std::execution::par_unseq => 2.402
std::execution::unseq => 8.737

x64-Release

std::execution::seq => 1.179
std::execution::par => 0.25
std::execution::par_unseq => 0.238
std::execution::unseq => 1.129

msvc源码描述

std::execution::sequenced_policy, std::execution::parallel_policy, std::execution::parallel_unsequenced_policy, std::execution::unsequenced_policy - cppreference.com

std::execution::seq, std::execution::par, std::execution::par_unseq, std::execution::unseq - cppreference.com

在以任何这些执行策略执行并行算法的过程中,若元素访问函数的调用因未捕获的异常退出,则调用 std::terminate,但实现可以定义以其他方式处理异常的额外执行策略。

源码

笔者看过gcc 11.2.0的实现,是用函数直接返回true-or-false的方式来区分。

但是注释基本没没什么描述,因此就不展示了。

本代码于msvc中<execution>

可见这里其实是定义了四个类型标签。标准没有定义对象内部的属性,这里是msvc的实现问题。

这里主要可以直接根据msvc的人话注释来理解标签的有含义。

namespace execution {class sequenced_policy {// indicates support for only sequential execution, and requests termination on exceptionspublic:using _Standard_execution_policy   = int;static constexpr bool _Parallelize = false;static constexpr bool _Ivdep       = false;};inline constexpr sequenced_policy seq{/* unspecified */};class parallel_policy {// indicates support by element access functions for parallel execution with parallel forward progress// guarantees, and requests termination on exceptionspublic:using _Standard_execution_policy   = int;static constexpr bool _Parallelize = true;static constexpr bool _Ivdep       = true;};inline constexpr parallel_policy par{/* unspecified */};class parallel_unsequenced_policy {// indicates support by element access functions for parallel execution with weakly parallel forward progress// guarantees, and requests termination on exceptions//// (at this time, equivalent to parallel_policy)public:using _Standard_execution_policy   = int;static constexpr bool _Parallelize = true;static constexpr bool _Ivdep       = true;};inline constexpr parallel_unsequenced_policy par_unseq{/* unspecified */};#if _HAS_CXX20class unsequenced_policy {// indicates support by element access functions for weakly parallel forward progress guarantees, and for// executing interleaved on the same thread, and requests termination on exceptions//// (at this time, equivalent to sequenced_policy except for the for_each family)public:using _Standard_execution_policy   = int;static constexpr bool _Parallelize = false;static constexpr bool _Ivdep       = true;};inline constexpr unsequenced_policy unseq{/* unspecified */};
#endif // _HAS_CXX20} // namespace execution

std::sequenced_policy seq

  1. 执行策略类型,用作对并行算法重载消歧义的独有类型,并要求并行算法的执行可以不并行化。以此策略调用(通常以 std::execution::seq 指定)的并行算法中,元素访问函数的调用在调用方线程中是非确定顺序的。
/*** 串行策略* indicates support for only sequential execution* 指示仅支持顺序执行* and requests termination on exceptions* 并在异常时终止请求*/
class sequenced_policy {// indicates support for only sequential execution, and requests termination on exceptions
public:using _Standard_execution_policy   = int;static constexpr bool _Parallelize = false;static constexpr bool _Ivdep       = false;
};inline constexpr sequenced_policy seq{/* unspecified */};

std::parallel_policy par

  1. 执行策略类型,用作对并行算法重载消歧义的独有类型,并指示并行算法的执行可以并行化。以此策略调用(通常以 std::execution::par 指定)的并行算法中,元素访问函数的调用允许在调用方线程,或由库隐式创建的用以支持并行算法执行的线程中执行。任何执行于同一线程中的这种调用彼此间是非确定顺序的,
/*** 并行执行策略* indicates support by element access functions for parallel execution with parallel forward* progress guarantees* 指示元素访问函数支持并行执行,并保证并行向前进度* and requests termination on exceptions* 并在异常时终止请求*/
class parallel_policy {// indicates support by element access functions for parallel execution with parallel forward// progress guarantees, and requests termination on exceptions
public:using _Standard_execution_policy   = int;static constexpr bool _Parallelize = true;static constexpr bool _Ivdep       = true;
};inline constexpr parallel_policy par{/* unspecified */};

std::parallel_unsequenced_policy par_unseq

  1. 执行策略类型,用作对并行算法重载消歧义的独有类型,并指示并行算法的执行可以并行化、向量化,或在线程间迁移(例如用亲代窃取式调度器)。以此策略调用的并行算法中,容许在未指定线程中以无序方式来执行元素访问函数调用,并相对于各个线程中的另一调用间无顺序。
/*** 并行无序执行策略* indicates support by element access functions for parallel execution with weakly parallel* forward progress guarantees* 指示元素访问函数支持并行执行,并提供弱并行向前进度保证* and requests termination on exceptions* 并在异常时终止请求* (at this time, equivalent to parallel_policy)* (此时,相当于并行策略)*/
class parallel_unsequenced_policy {// indicates support by element access functions for parallel execution with weakly parallel// forward progress guarantees, and requests termination on exceptions//// (at this time, equivalent to parallel_policy)
public:using _Standard_execution_policy   = int;static constexpr bool _Parallelize = true;static constexpr bool _Ivdep       = true;
};inline constexpr parallel_unsequenced_policy par_unseq{/* unspecified */};

std::unsequenced_policy unseq

  1. 执行策略类型,用作对并行算法重载消歧义的独有类型,并指示可将算法的执行向量化,例如在单个线程上使用操作多个数据项的指令执行。
#if _HAS_CXX20
/*** 无序执行策略* indicates support by element access functions for weakly parallel forward progress guarantees* 指示元素访问函数支持弱并行向前进度保证* and for executing interleaved on the same thread* 支持在同一线程上交错执行* and requests termination on exceptions* 以及在异常时终止请求* (at this time, equivalent to sequenced_policy except for the for_each family)* (此时,相当于sequenced_policy,除了for_each一类)*/
class unsequenced_policy {// indicates support by element access functions for weakly parallel forward progress// guarantees, and for executing interleaved on the same thread, and requests termination on// exceptions//// (at this time, equivalent to sequenced_policy except for the for_each family)
public:using _Standard_execution_policy   = int;static constexpr bool _Parallelize = false;static constexpr bool _Ivdep       = true;
};inline constexpr unsequenced_policy unseq{/* unspecified */};
#endif  // _HAS_CXX20

END

关注我,学习更多C/C++,算法,计算机知识

相关文章:

  • 【C++笔记】异常与智能指针
  • 高架学习笔记之UML图概要
  • 小程序UI设计规范,界面设计尺寸详解
  • 囊括所有大模型:高质量中文预训练模型大模型多模态模型大语言模型集合
  • 【QQ版】QQ群短剧机器人源码 全网短剧机器人插件
  • Python数据库编程全指南SQLite和MySQL实践
  • Centos服务器Open Gauss 部署
  • Python练习
  • k8s安装traefik作为ingress
  • 科技下乡:数字乡村改变乡村生活方式
  • 物联网实战--入门篇之(三)嵌入式STM32
  • 如何应对复杂软件工程的开发流程?
  • JVM(二)——垃圾回收
  • 新网站收录时间是多久,新建网站多久被百度收录
  • 沃尔玛百货有限公司 企业网页设计制作 企业html网页成品 跨国公司网页设计开发 web前端开发,html+css网页设计素材,静态html学生网页成品源码
  • 07.Android之多媒体问题
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • Android优雅地处理按钮重复点击
  • Create React App 使用
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • log4j2输出到kafka
  • nodejs:开发并发布一个nodejs包
  • React Native移动开发实战-3-实现页面间的数据传递
  • 汉诺塔算法
  • 机器学习 vs. 深度学习
  • 聊聊directory traversal attack
  • 七牛云假注销小指南
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • #Linux(make工具和makefile文件以及makefile语法)
  • ( 10 )MySQL中的外键
  • (1)STL算法之遍历容器
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (Git) gitignore基础使用
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (转)大型网站的系统架构
  • (转)我也是一只IT小小鸟
  • .Net - 类的介绍
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • .ui文件相关
  • /bin、/sbin、/usr/bin、/usr/sbin
  • [1] 平面(Plane)图形的生成算法
  • [Android]Android开发入门之HelloWorld
  • [BT]BUUCTF刷题第4天(3.22)
  • [BT]BUUCTF刷题第8天(3.26)
  • [BUG] Authentication Error
  • [CTO札记]如何测试用户接受度?
  • [Docker]十.Docker Swarm讲解
  • [HDU5685]Problem A