c++ 函数有没有返回执行策略的方法?

whlutmcx  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(92)

我最近一直在做一个项目,我遇到了一个问题,我不想在小向量上使用 std::execution::par,因为这会产生开销。
从理论上讲,这个问题可以通过函数来解决,该函数返回 std::execution::parstd::execution::seq,具体取决于向量的总大小乘以每个元素的大小,并将其与一个固定值进行比较。但问题是,它们是不同类型的,这意味着它们无法返回。我们也可以只返回一个bool,看看并行是否值得,但这会导致讨厌的分支,我不希望这样。我只是想知道有没有一种方法可以巧妙地解决这个问题

3ks5zfa0

3ks5zfa01#

嗯,他们把这些类型区分开来;大概是为了避免这种运行时决策。这至少会导致代码膨胀,因为现在每个算法都必须被示例化。但如果你认为这是必要的,这是我能想到的最短的:

#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()); });
}

相关问题