Different execution policies at runtime(运行时不同的执行策略)
问题描述
在 C++17 中,algorithm
标头中的许多函数现在可以采用执行策略.例如,我可以定义和调用这样的函数:
In C++17, a number of functions in the algorithm
header now can take an execution policy. I can for example define and call a function like this:
template <class ExecutionPolicy>
void f1(const std::vector<std::string>& vec, const std::string& elem, ExecutionPolicy&& policy) {
const auto it = std::find(
std::forward<ExecutionPolicy>(policy),
vec.cbegin(), vec.cend(), elem
);
}
std::vector<std::string> vec;
f1(vec, "test", std::execution::seq);
但是我还没有找到在运行时使用不同策略的好方法.例如,当我想根据某些输入文件使用不同的策略时.
However I haven't found a good way to use different policies at runtime. For example when I want to use a different policy depending on some input file.
我尝试了各种变体,但最终问题总是出在不同类型的 std::execution::seq
、std::execution::par
和 std::execution::par_unseq
.
I toyed around with variants, but in the end the problem was always the different types of std::execution::seq
, std::execution::par
and std::execution::par_unseq
.
一个有效但繁琐的解决方案如下所示:
A working but cumbersome solution would look like this:
void f2(const std::vector<std::string>& vec, const std::string& elem, const int policy) {
const auto it = [&]() {
if (policy == 0) {
return std::find(
std::execution::seq,
vec.cbegin(), vec.cend(), elem
);
}
else if (policy == 1) {
return std::find(
std::execution::par,
vec.cbegin(), vec.cend(), elem
);
}
else{
return std::find(
std::execution::par_unseq,
vec.cbegin(), vec.cend(), elem
);
}
};
}
f2(vec, "test", 0);
有没有我忽略的更优雅的解决方案?
Is there any more elegant solution I'm overlooking?
也许我应该更精确.假设目标是将策略保存在一个变量中,该变量可以具有三个策略中的任何一个.该变量应该是函数的参数.
edit: maybe I should be more precise. Let's say the goal is to save the policy in a variable that can have either of the three policies. That variable should be a parameter to the function.
推荐答案
这里的标准方法是将类型的选择与类型的使用分开:后者采用由前者的非模板函数(或模板参数较少的函数模板)多次实例化的函数模板的形式.
The standard approach here is to separate the selection of a type from the use of the type: the latter takes the form of a function template instantiated several times by the former non-template function (or function template with fewer template parameters).
为了避免在这两层之间复制普通参数,请使用通用 lambda 作为模板.为避免重复选择逻辑,请制作一个函数模板,使用适当的策略调用任何 lambda:
To avoid duplicating the normal parameters between these two layers, use a generic lambda as the template. To avoid duplicating the selection logic, make a function template that calls whatever lambda with the appropriate policy:
enum Policy {seq,par,par_unseq};
template<class F>
auto maybe_parallel(F f,Policy p) {
switch(p) {
case seq: return f(std::execution::seq);
case par: return f(std::execution::par);
default: return f(std::execution::par_unseq);
}
}
auto f2(const std::vector<std::string>& vec,
const std::string& elem,Policy p) {
return maybe_parallel
([&](auto &pol) {return std::find(pol,vec.begin(),vec.end(),elem);},p);
}
这篇关于运行时不同的执行策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:运行时不同的执行策略
基础教程推荐
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- Windows Media Foundation 录制音频 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01