当前位置: 首页 > 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学生网页成品源码
  • @jsonView过滤属性
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • docker python 配置
  • idea + plantuml 画流程图
  • JavaScript 一些 DOM 的知识点
  • Linux Process Manage
  • mysql_config not found
  • Promise面试题,控制异步流程
  • React16时代,该用什么姿势写 React ?
  • SpiderData 2019年2月16日 DApp数据排行榜
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • vue脚手架vue-cli
  • windows下如何用phpstorm同步测试服务器
  • 爬虫模拟登陆 SegmentFault
  • 前端临床手札——文件上传
  • 深入浅出Node.js
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 使用 QuickBI 搭建酷炫可视化分析
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • 从如何停掉 Promise 链说起
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • 积累各种好的链接
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​批处理文件中的errorlevel用法
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #Spring-boot高级
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (二)PySpark3:SparkSQL编程
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (附源码)计算机毕业设计大学生兼职系统
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • .net FrameWork简介,数组,枚举
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)