c:OpenMP和非随机访问STL容器 – 可能的解决方法

所以对于SO和整体来说,对于如何使OpenMP易于使用的#pragma指令与C的同样易于使用的STL容器配合,存在着许多困惑和沮丧.

每个人都在谈论STL向量的解决方案,但是非随机访问/双向容器(如地图,列表,集合等)呢?

我遇到这个问题,并设计了一个非常简单明了的解决方法.我在这里提供STL地图,但它是可以概括的.

串行版本:

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

我提出的使用OpenMP与STL映射的解决方案:

//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  */   }

}

解决方法

OpenMP提供从版本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   */  }
}

当然,迭代之间的数据依赖关系不应该存在,这样才能正常工作.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...