有条件地并行填充向量

时间:2018-11-22 12:37:12

标签: c++ multithreading algorithm vector

我想编写以下代码的多线程版本

template<typename Out, typename In, typename Cond, typename Func>
std::vector<Out> collect(std::vector<In> const&values,
                         Cond const&cond, Func const&func)
{
    std::vector<Out> result;
    for(auto const&val : values)
        if(cond(val))
            result.emplace_back(func(val));
    return result;
}

所选元素的顺序无关紧要。

一种简单的方法是

template<typename Out, typename In, typename Cond, typename Func>
std::vector<Out> collect(std::vector<In> const&values,
                         Cond const&cond, Func const&func)
{
    std::vector<Out> result(values.size());
    std::atomic<size_t> index = 0;
    // some multithreaded for loop implementation
    parallel_for(size_t(0),values.size(),[&](size_t i) {
        if(cond(values[i]))
            result[index++] = func(values[i]);
    });
    result.resize(index);
    return result;
}

(当然,初始化result是串行的,但在这里我们忽略它)。这似乎可行,但可能不是无锁的。有没有更好的办法?特别是,是否可以避免分配过多的数据(如果只选择了少数输入数据)?

问题与std::copy_if非常相似(可能是std::transform_if存在)-并行版本std::copy_if(std::par,...)的实现方式是什么(它是C ++ 17,但我只能使用C ++ 11)?

1 个答案:

答案 0 :(得分:0)

一种不错的方法是使用在最后合并的线程局部向量。这个答案(特别是最后一个代码示例)如果不是使用OMP的事实,将是一个很好的副本:

https://stackoverflow.com/a/18671256/9528746

编辑:更改为更好的答案。