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

c++: OpenMP and non-random-access STL containers - a possible workaround

本文关键字:一种 方法 解决 OpenMP 非随机 访问 容器 STL c++      更新时间:2023-10-16

所以在SO和一般的互联网上,关于如何使OpenMP易于使用的#pragma指令与C++同样易于使用的STL容器配合使用,存在很多困惑和沮丧。

每个人都在谈论STL vector的解决方法,但是非随机访问/双向容器,如maplistset等呢?

我遇到了这个问题,并设计了一个非常简单,明显的解决方法。 我在这里为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  */   }
}

OpenMP 提供了从版本 3.0 开始的task结构,这对于与 STL 一起使用非常有用:

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

当然,迭代之间的数据依赖关系不应该存在,这要起作用。

相关文章: