hku-mars / ikd-Tree

This repository provides implementation of an incremental k-d tree for robotic applications.
GNU General Public License v2.0
630 stars 174 forks source link

error about Nearest_Search with multi thread #20

Closed HeXu1 closed 2 years ago

HeXu1 commented 2 years ago

Hi, thanks for your great works. ikdtree works well with one thread but not with multi thread. the output are " Error in `./ikdtreeLoclization': double free or corruption (fasttop): 0x00007fcd1c000b50 " and the test demo are:

    std::vector<PointType ,Eigen::aligned_allocator<PointType>> pointNear;
    std::vector<float> nearDis(nearNum);

    omp_set_num_threads(3);
    #pragma omp parallel for 
    for (int j = 0; j < lidarCurW->size() ; j++)
    {
            PointType pointJ=lidarCurW->points[j];
            ikdtree.Nearest_Search(pointJ,nearNum,pointNear,nearDis,5.0);
 }

hope for your reply, thanks

Ecstasy-EC commented 2 years ago

Hi @HeXu1

After reading your code, I am sure that the memory conflict results from your vector pointNear. Since you are using multi-thread, you should use different memories for different threads. However, you are using pointNear for all threads.

A better solution would be declaring a vector of std::vector<PointType ,Eigen::aligned_allocator<PointType>> and applying the pointer to the nearest points vector to the search function.

You might refer to the code src/laserMapping.cpp in FAST-LIO2, which provides a good example for multi-thread nearest search. In that code, a vector of vector vector<PointVector> Nearest_Points is declared and a pointer to the vector &points_near = Nearest_Points[i] is used for nearest search.

Hope my answer would help you.

HeXu1 commented 2 years ago

Screenshot from 2022-02-23 15-33-36

yes ,it works. It seems that nearSearch effectiveness is not very robust. For example, I test it with icp registration ,the nearSearch time seems big difference between searches! I have print the search time in every iter as the about picture shows. hope for your reply,thanks.

HeXu1 commented 2 years ago

image

the blue line is ikdtree search time and orange line is pcl kdtree time(ms). it was stable most time,but may be exhausted occasionally.

Ecstasy-EC commented 2 years ago

@HeXu1

Well, it is not surprising for me about such results.

We did observe the jumping time consumption in our own tests, which was resulted from the double-thread re-building process. When you have inserted too many points into the tree, the balance property of the tree is broken heavily. In our design, the tree will be rebuilt entirely in the second thread to achieve a balanced structure. Note that we use the double thread policy for most of the rebuilding process to preserve real-time performance in the main thread. If you are requesting a knn search during the rebuilding process, the tree structure is bad thus the search is slow. Once the rebuilding process is done, the search will behave as normal time as the tree structure has been well balanced.

If you are expected to eliminate the jumping time in your code, you might need to slow down your running frequency or simply apply a short break (usleep) before your search.

HeXu1 commented 2 years ago

Thanks a lot, adding usleep before search seems slow down heavily. I will try the filter strategy just like what fast-lio do before add points. If i didn't misunderstand ,this will slow down the rebuild frequency.