2010-03-25 160 views
18

我正在尝试使用openmp通过std :: set多线程循环。当我写了下面的代码 -在openmp中通过std容器进行迭代

#pragma omp parallel for 
    for (std::set<A>::const_iterator i = s.begin(); i != s.end(); ++i) { 
      const A a = *i; 
      operate(a); 
    } 

我得到这个错误:

error: invalid type for iteration variable 'i' 
error: invalid controlling predicate 
error: invalid increment expression. 

是否有使用OpenMP通过STD容器迭代另一个,正确的方法? 我知道我可以使用int i并从0重复s.size()和循环体中的迭代器或operator[],但这看起来不太干净。

+1

哪个编译器? GCC有一个并行的实现(http://gcc.gnu.org/onlinedocs/libstdc++/manual/parallel_mode.html)'std :: for_each',它应该为你做好诀窍。也许你也可以看看那里的源代码?另见http://algo2.iti.kit.edu/singler/mcstl/。 – stephan 2010-03-25 09:08:15

回答

21

stl迭代器的循环并行化仅在OpenMP 3.0以后才起作用,并且仅适用于随机访问迭代器(例如vectordeque)。你应该能够做这样的事情:

#pragma omp parallel { 
    for (std::set<A>::const_iterator i = s.begin(); i != s.end(); ++i) { 
     #pragma omp single nowait { 
     operate(*i); 
     } 
    } 
} 

开销是相当大的,但因为在整个序列中的每个线程迭代(但仅限于它的一些执行operate)。你的方法使用int i更高效。

作为替代看看GCC的并行实施std::for_each。看到我的评论。

编辑:STL Parallism TS最有可能成为C++ 17的一部分,将来可能是迭代标准容器的一个很好的选择。

+0

谢谢! MCSTL就是我需要的。 – 2010-03-26 12:38:01

+0

'std :: set'没有'operator []',msvc只支持openmp 2.0:/ – quimnuss 2016-03-15 10:48:39

+1

@quimnuss:msvc的[Parallel STL](https://parallelstl.codeplex.com/)可能会有所帮助。 [Parallelism TS](https://isocpp.org/files/papers/P0024R2.html)很可能是C++ 17的一部分,所以这应该是合理的未来的证明(但可能仍然有错误,而不是功能完成,我没有太紧密地跟踪MS实施)。 – stephan 2016-03-15 11:35:15