我想编写以下代码的多线程版本
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)?
答案 0 :(得分:0)
一种不错的方法是使用在最后合并的线程局部向量。这个答案(特别是最后一个代码示例)如果不是使用OMP的事实,将是一个很好的副本:
https://stackoverflow.com/a/18671256/9528746
编辑:更改为更好的答案。