c ++:OpenMP和非随机访问STL容器 - 一种可能的解决方法

cmo*_*cmo 10 c++ parallel-processing multithreading stl openmp

因此,在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   */  }
Run Code Online (Sandbox Code Playgroud)

我提出的将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]    */  }
Run Code Online (Sandbox Code Playgroud)

我不是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  */   }

}
Run Code Online (Sandbox Code Playgroud)

Hri*_*iev 5

OpenMP提供了task从3.0版本开始的构造,这对于STL非常有用:

for (std::map<A,B>::iterator it = my_map.begin();
        it != my_map.end();
        ++it)       
{
   #pragma omp task
   { /* do work with  it   */  }
}
Run Code Online (Sandbox Code Playgroud)

当然,迭代之间的数据依赖性不应该存在以使其工作.