【问题标题】:Adding to a vector in multithread在多线程中添加到向量
【发布时间】:2018-04-05 11:22:13
【问题描述】:

我想在特定条件下选择点并将所选点放入新容器中。

void IntervalMapEstimator::extract_relevant_points_multithread(std::vector<Point3D>&  relevant_points ,std::vector<Point3D>& pointcloud, doubleIE cell_min_angle_sensor_rot, doubleIE cell_max_angle_sensor_rot)
{
    relevant_points.reserve (pointcloud.size ());

#pragma omp parallel for shared (relevant_points, pointcloud, cell_min_angle_sensor_rot, cell_max_angle_sensor_rot) num_threads(5)
        for(int i = 0; i < pointcloud.size(); i++) {
           if( -- condition -- ){
#pragma omp critical(push_in_relevant_points)
                     relevant_points.push_back(pointcloud[i]);                     
            }
        }
}

所以我有一个使用 openMp 的多线程环境,问题是,每次条件选择一个点时,我都必须使用我的关键子句(它基本上像 std::lock_guard 一样工作)将值推送到相关点容器。所以使用这个容器存在瓶颈。

我正在寻找解决问题并提高效率的方法,您有什么想法吗?

【问题讨论】:

  • 创建一个本地向量,然后在循环完成后将这些本地数组与主向量合并一次?
  • @MikeVine 将此作为答案发布
  • 我不确定我是否理解你所说的,但听起来问题是一样的。我将不得不使用不同的线程访问本地向量。
  • @tony497 local 表示 thread-local,这样每个线程都有自己的向量。您可以实现这一点,例如,通过在 #pragma omp parallel 部分中声明此类向量,然后仅使用 #pragma omp for
  • 您可以尝试使用为并发构建的其他数据结构,而不是std::vector。例如,tbb::concurrent_vectorsoftware.intel.com/en-us/node/506203

标签: c++ multithreading optimization design-patterns


【解决方案1】:

好的,这是我的解决方案,它效果不佳,循环的每次迭代平均只获得几微秒(我的样本约为 15000 点)。 因为最后我仍然需要停止计算,将本地线程的结果添加到我的最终向量中。

void IntervalMapEstimator::extract_relevant_points_multithread_with_localvector(std::vector<Point3D>&  relevant_points ,std::vector<Point3D>& pointcloud, doubleIE cell_min_angle_sensor_rot, doubleIE cell_max_angle_sensor_rot)
{
#pragma omp parallel num_threads(5)
    {
        std::vector<Point3D> local_relevant_points;

        #pragma omp for
            for(int i = 0; i < pointcloud.size(); i++) {

                // Check whether the cell is between the 2nd and 3rd quadrant (--> e.g. -170 to 170°)
                if (cell_min_angle_sensor_rot < 0 && cell_max_angle_sensor_rot >= 0 && abs(cell_min_angle_sensor_rot) > M_PI/2 && abs(cell_max_angle_sensor_rot) > M_PI/2) {
                    // Point must be smaller than the minimum angle and bigger than the max angle (e.g. min-angle: -1.5 max-angle: 1.5 point angle bigger than 1.5 or smaller than -1.5)
                    if (pointcloud[i].pol_sensor_rot.phi <= cell_min_angle_sensor_rot || pointcloud[i].pol_sensor_rot.phi >= cell_max_angle_sensor_rot ) {
                        local_relevant_points.push_back(pointcloud[i]);
                    }
                } else {
                     if (pointcloud[i].pol_sensor_rot.phi >= cell_min_angle_sensor_rot && pointcloud[i].pol_sensor_rot.phi <= cell_max_angle_sensor_rot ) {
                         local_relevant_points.push_back(pointcloud[i]);
                     }
                }
            }

        #pragma omp critical
            {
                if(!local_relevant_points.empty())
                    relevant_points.insert (relevant_points.end (),local_relevant_points.begin (),local_relevant_points.end ());
            }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 2015-01-08
    相关资源
    最近更新 更多