所以在 SO 和整个 Internet 上,对于如何使 OpenMP 的易于使用的#pragma
指令与 C++ 的同样易于使用的 STL 容器相配合,存在很多困惑和挫败感。
每个人都在谈论 STL 的变通方法vector
,但非随机访问/双向容器,如map
、list
、set
等呢?
我遇到了这个问题,并设计了一个非常简单、明显的解决方法。我在这里为 STL 介绍它map
,但它显然是可推广的。
系列版本:
for (std::map<A,B>::iterator it = my_map.begin();
it != my_map.end();
++it)
{ /* do work with it */ }
我提出的将 OpenMP 与 STL 结合使用的解决方案map
:
//make an array of iterators.
int loop_length = my_map.size();
std::map<A,B>::iterator loop_array[ loop_length ];
std::map<A,B>::iterator allocate_it = my_map.begin();
for (int j=0; j<loop_length; ++j)
loop_array[j] = allocate_it++;
// now you can use OpenMP as usual:
#pragma omp parallel for
for (uint j=0; j<loop_length; ++j)
{ /* do work with loop_array[j] */ }
但是,我远非 OpenMP 专家,因此我想知道我提出的解决方法是否有效且是良好的实践。
请假设程序员负责在 for 循环中对 STL 容器进行线程安全处理。
最后,我提出的解决方案是否比以下普遍提出的解决方案更有效(请参阅对此 SO 问题的回答),因为在我的解决方案中,每个线程不会遍历整个容器?
#pragma omp parallel
{
for (std::map<A,B>::iterator it = my_map.begin();
it != my_map.end();
++it)
#pragma single nowait
{ /* do work */ }
}