函数返回执行策略的任何方法?

Any way for a function to return an execution policy?

提问人:Bahram Gozalov 提问时间:10/18/2023 最后编辑:ShadowRangerBahram Gozalov 更新时间:10/19/2023 访问量:117

问:

我最近一直在做一个项目,我遇到了一个问题,我不想在小向量上使用 std::execution::p ar,因为这会产生开销。

好吧,从理论上讲,这可以通过返回 std::execution::p ar 或 std::execution::seq 的函数来解决,具体取决于向量的总大小乘以每个元素的大小并将其与固定值进行比较。但问题是它们属于不同的类型,这意味着它们无法返回。我们也可以只返回一个布尔值,无论并行是否值得,但这会导致令人讨厌的分支,我不希望这样。 我只是想知道这是否是一种我可以巧妙地解决这个问题的方法

C++ 并行处理 17 C++ 20 标准

评论

1赞 Pete Becker 10/18/2023
该实现将足够智能,不会为小序列启动一堆线程。
1赞 Ben Voigt 10/18/2023
@PeteBecker:并行化的决定难道不需要知道各个任务的成本有多高吗?
1赞 joergbrech 10/18/2023
如果返回类型是依赖于运行时参数(向量大小)的两种类型的变体,则可以使用 .std::variant
2赞 joergbrech 10/18/2023
请删除 C++11 和 C++14 标签。AFAIK 执行策略是 C++17 的最低要求。
0赞 Pete Becker 10/18/2023
@BenVoigt - 是的,更大的单个任务可以从较低的门槛中受益。实现无法知道任务的大小,因此存在一个合理的问题。

答:

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
听起来不错