使用openMP进行多线程崩溃

时间:2018-04-03 12:32:53

标签: c++ multithreading bigdata openmp

我的功能是对17000点(大约可以波动)的点云进行排序,以提取此点中的相关点并将它们存储在矢量中。一切正常,但速度很慢。所以我试图使用openMp来并行化任务,但我遇到了崩溃。

这是多线程版本,它不起作用:

7fcc93737000-7fcc9374b000 r-xp 00012000 103:05 7078283                   /lib/x86_64-linux-gnu/ld-2.23.so
7fcc938a3000-7fcc938f7000 rw-p 00000000 00:00 0 
7fcc9391e000-7fcc9392c000 rw-p 00000000 00:00 0 
7fcc93937000-7fcc93939000 rw-p 00000000 00:00 0 
7fcc93947000-7fcc9394a000 rw-p 00000000 00:00 0 
7fcc9394a000-7fcc9394b000 r--p 00025000 103:05 7078283                   /lib/x86_64-linux-gnu/ld-2.23.so
7fcc9394b000-7fcc9394c000 rw-p 00026000 103:05 7078283                   /lib/x86_64-linux-gnu/ld-2.23.so
7fcc9394c000-7fcc9394d000 rw-p 00000000 00:00 0 
7fff20b58000-7fff20b7a000 rw-p 00000000 00:00 0                          [stack]
7fff20bb8000-7fff20bbb000 r--p 00000000 00:00 0                          [vvar]
7fff20bbb000-7fff20bbd000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
[interval_map-1] process has died [pid 12700, exit code -6, cmd /home/catkin_ws/SWC_INTERVAL_MAP/devel/lib/interval_map_test/interval_map_test __name:=interval_map __log:=/home/.ros/log/615acdf0-3714-11e8-bc07-9cebe84f847e/interval_map-1.log].
log file: /home/.ros/log/615acdf0-3714-11e8-bc07-9cebe84f847e/interval_map-1*.log
all processes on machine have died, roslaunch will exit
shutting down processing monitor...
... shutting down processing monitor complete
done

这里是我对输出的反应:

    Could not send response error 500: javax.servlet.ServletException: javax.servlet.ServletException: java.lang.RuntimeException: java.lang.IllegalStateException: org.springframework.dao.TransientDataAccessResourceException: StatementCallback; SQL [IF EXISTS (SELECT name FROM sys.databases WHERE name = N'utv_johan')
BEGIN
ALTER DATABASE utv_johan SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
drop database utv_johan;
END
]; ALTER DATABASE failed because a lock could not be placed on database 'utv_johan'.

目前,我最好的猜测是有一个等待列表,用于查看点云向量内的值或者相关点向量上的push_back,它们越来越大,最终爆炸堆栈。 有人对这个问题有任何想法吗?

2 个答案:

答案 0 :(得分:0)

实际上,你在这里想要实现的非常类似于使用向量作为缩减变量的减少。

如果我想并行化它,我将如何处理它:

colourImg = Image.open("test.png")
colourPixels = colourImg.convert("RGB")
colourArray = np.array(colourPixels.getdata())

df = pd.DataFrame(colourArray, columns=["red","green","blue"])

这个想法是并行进行本地处理,然后在全局输出中累积本地结果。 我通过计算结果的预期大小添加了额外的细化,以便提前保留正确的大小以节省额外的冗长内存分配。

现在,有2个警告:

  1. 我没有编译它所以那里可能会有一些拼写错误;
  2. 我不确定这种并行化会带来多大好处,因为整个过程可能太短暂而且内存受限......但是你还是去了。

答案 1 :(得分:0)

以下是我的功能现在的样子:

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++) {
            //int numThread = omp_get_thread_num();
            //std::cout << "numThread = " << numThread << std::endl;

            // 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 ) {                   
#pragma omp critical(push_in_relevant_points)
                    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 ) {
#pragma omp critical(push_in_relevant_points)
                     relevant_points.push_back(pointcloud[i]);
                 }
            }
        }
}

我使用了mop critical而不是guard_lock来获得更多的一致性,我在开始时做了一个保留。 因为在我的情况下,related_points矢量永远不会比点云大,并且大部分时间他只包含50到100个元素。我不再使用矢量的副本,而是参考。