标准库标头 <execution> (C++17)学习

此头文件是算法库的一部分。本篇介绍策略类型的一些应用示例:

is_execution_policy

(C++17)

测试一个类是否表示某种执行策略
(类模板)

在命名空间 std::execution 定义

sequenced_policyparallel_policyparallel_unsequenced_policyunsequenced_policy

(C++17)(C++17)(C++17)(C++20)

执行策略类型
(类)

常量

在命名空间 std::execution 定义

seqparpar_unsequnseq

(C++17)(C++17)(C++17)(C++20)

全局执行策略对象
(常量)

 首先看execution在VS2022里的定义

namespace execution {
    _EXPORT_STD 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;
    };

    _EXPORT_STD inline constexpr sequenced_policy seq{/* unspecified */};

    _EXPORT_STD 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;
    };

    _EXPORT_STD inline constexpr parallel_policy par{/* unspecified */};

    _EXPORT_STD 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;
    };

    _EXPORT_STD inline constexpr parallel_unsequenced_policy par_unseq{/* unspecified */};

#if _HAS_CXX20
    _EXPORT_STD 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 for_each(_n), destroy(_n),
        // uninitialized_default_construct(_n), and uninitialized_value_construct(_n))
    public:
        using _Standard_execution_policy   = int;
        static constexpr bool _Parallelize = false;
        static constexpr bool _Ivdep       = true;
    };

    _EXPORT_STD inline constexpr unsequenced_policy unseq{/* unspecified */};
#endif // _HAS_CXX20

} // namespace execution

示例代码:

#include <algorithm>
#include <chrono>
#include <cstdint>
#include <iostream>
#include <random>
#include <vector>
#include <ctime>
#include <execution>
#include <string>


//https://zh.cppreference.com/w/cpp/algorithm/execution_policy_tag
//https://blog.csdn.net/CUBE_lotus/article/details/137159423

#ifdef PARALLEL
#include <execution>
namespace execution = std::execution;
#else
enum class execution { seq, unseq, par_unseq, par };
#endif

void measure([[maybe_unused]] auto policy, std::vector<std::uint64_t> v)
{
    const auto start = std::chrono::steady_clock::now();
#ifdef PARALLEL
    std::sort(policy, v.begin(), v.end());
#else
    std::sort(v.begin(), v.end());
#endif
    const auto finish = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(finish - start)
        << '\n';
};

/**
  * 辅助计时类
  */
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 >= 201902L
    Timer timer("std::execution::unseq");
    std::sort(std::execution::unseq, arr.begin(), arr.end());
#endif
}


int main()
{
    std::vector<std::uint64_t> v(1'000'000);
    std::mt19937 gen{ std::random_device{}() };
    std::ranges::generate(v, gen);//C++ 20 标准

    measure(execution::seq, v);
    measure(execution::unseq, v);
    measure(execution::par_unseq, v);
    measure(execution::par, v);
    std::cout << "__cplusplus=============================" << __cplusplus << "\n";

    std::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);


    std::cout << "hello world\n";
}

运行结果:

参考:

https://zh.cppreference.com/w/cpp/algorithm/execution_policy_tag
https://blog.csdn.net/CUBE_lotus/article/details/137159423

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值