提问人:Bahram Gozalov 提问时间:10/18/2023 最后编辑:ShadowRangerBahram Gozalov 更新时间:10/19/2023 访问量:117
函数返回执行策略的任何方法?
Any way for a function to return an execution policy?
问:
我最近一直在做一个项目,我遇到了一个问题,我不想在小向量上使用 std::execution::p ar,因为这会产生开销。
好吧,从理论上讲,这可以通过返回 std::execution::p ar 或 std::execution::seq 的函数来解决,具体取决于向量的总大小乘以每个元素的大小并将其与固定值进行比较。但问题是它们属于不同的类型,这意味着它们无法返回。我们也可以只返回一个布尔值,无论并行是否值得,但这会导致令人讨厌的分支,我不希望这样。 我只是想知道这是否是一种我可以巧妙地解决这个问题的方法
答:
5赞
Homer512
10/18/2023
#1
好吧,他们使这些类型与众不同;大概是为了避免这种运行时决策。这至少会导致严重的代码膨胀,因为现在每个算法都必须实例化。但是,如果您认为有必要,这是我能想到的最短的:
#include <algorithm>
#include <execution>
#include <thread>
#include <variant>
using execution_variant = std::variant<
std::execution::sequenced_policy, std::execution::parallel_policy>;
execution_variant select_execution(std::size_t items)
{
if(items > std::thread::hardware_concurrency() * 16)
return std::execution::par;
return std::execution::seq;
}
void sort(std::vector<int>& vec)
{
std::visit([&](auto policy) {
std::sort(policy, vec.begin(), vec.end()); },
select_execution(vec.size()));
}
或者使用助手使呼叫站点更简洁:
struct Execution
{
execution_variant var;
template<class Fun>
auto operator()(Fun&& fun) const
{ return std::visit(fun, var); }
static Execution select(std::size_t items)
{
if(items > std::thread::hardware_concurrency() * 16)
return {std::execution::par};
return {std::execution::seq};
}
};
void sort(std::vector<int>& vec)
{
Execution::select(vec.size())([&](auto policy) {
std::sort(policy, vec.begin(), vec.end()); });
}
评论
0赞
Bahram Gozalov
10/19/2023
有没有办法使它变得灵活,而不仅仅是std::sort?
0赞
Homer512
10/19/2023
@BahramGozalov只是替换该 lambda 的内容
0赞
Bahram Gozalov
10/19/2023
听起来不错
评论
std::variant