此头文件是算法库的一部分。本篇介绍策略类型的一些应用示例:
类 | |
(C++17) | 测试一个类是否表示某种执行策略 (类模板) |
在命名空间 | |
sequenced_policyparallel_policyparallel_unsequenced_policyunsequenced_policy (C++17)(C++17)(C++17)(C++20) | 执行策略类型 (类) |
常量 | |
在命名空间 | |
(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