【发布时间】:2012-05-03 14:03:29
【问题描述】:
在 SO 和整个互联网上,对于如何使 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 容器进行线程安全处理。
最后,我提出的解决方案是否比以下普遍提出的解决方案(see answer to this SO Question) 更有效,因为在我的解决方案中,每个线程不会遍历整个容器?
#pragma omp parallel
{
for (std::map<A,B>::iterator it = my_map.begin();
it != my_map.end();
++it)
#pragma single nowait
{ /* do work */ }
}
【问题讨论】:
-
我怀疑这会更快(至少当
A和B很大时,否则您可以将它们复制到vector中)。但是你有没有尝试过你的问题?是不是更快? -
@larsmans 我没有做过任何性能测试,也没有真正计划过(对不起)。我已经有一个以串行方式编写的大型复杂程序,到处都有 STL 容器,并且正在尝试对某些 STL-for-loop 进行多线程处理。因此,我不能轻易隔离和计时......
-
即使您将容器的内容复制到
vector以进行测试也不行? -
对不起,如果我的问题很愚蠢,但您能不能简单地遍历
j,然后通过allocate_it+j访问元素,其中分配它的设置与您的帖子中一样。 -
@Azrael3000 但是迭代器算术不是只对随机访问迭代器有效吗(比如
vector)?map,list,set,只使用双向迭代器。
标签: c++ multithreading stl parallel-processing openmp