Ich habe eine Funktion erstellt, die die normalen Vektoren einer 3D-Punktwolke schätzt und es braucht viel Zeit, um auf einer Wolke der Größe 2 Millionen zu laufen. Ich möchte multi-thread, indem Sie die gleiche Funktion auf zwei verschiedenen Punkten gleichzeitig aufrufen, aber es hat nicht funktioniert (es erstellt Hunderte von Threads). Hier ist, was ich versucht:Wie wird Multithreading innerhalb einer Schleife verwendet, die in C++ durch eine Punktwolke iteriert?
// kd-tree used for finding neighbours
pcl::KdTreeFLANN<pcl::PointXYZRGB> kdt;
// cloud iterators
pcl::PointCloud<pcl::PointXYZRGB>::iterator cloud_it = pt_cl->points.begin();
pcl::PointCloud<pcl::PointXYZRGB>::iterator cloud_it1;
pcl::PointCloud<pcl::PointXYZRGB>::iterator cloud_it2;
pcl::PointCloud<pcl::PointXYZRGB>::iterator cloud_it3;
pcl::PointCloud<pcl::PointXYZRGB>::iterator cloud_it4;
// initializing tree
kdt.setInputCloud(pt_cl);
// loop exit condition
bool it_completed = false;
while (!it_completed)
{
// initializing cloud iterators
cloud_it1 = cloud_it;
cloud_it2 = cloud_it++;
cloud_it3 = cloud_it++;
if (cloud_it3 != pt_cl->points.end())
{
// attaching threads
boost::thread thread_1 = boost::thread(geom::vectors::find_normal, pt_cl, cloud_it1, kdt, radius, max_neighbs);
boost::thread thread_2 = boost::thread(geom::vectors::find_normal, pt_cl, cloud_it2, kdt, radius, max_neighbs);
boost::thread thread_3 = boost::thread(geom::vectors::find_normal, pt_cl, cloud_it3, kdt, radius, max_neighbs);
// joining threads
thread_1.join();
thread_2.join();
thread_3.join();
cloud_it++;
}
else
{
it_completed = true;
}
}
Wie Sie sehen Ich versuche, die gleiche Funktion auf 3 verschiedenen Punkten in der gleichen Zeit zu nennen. Irgendwelche Vorschläge, wie das funktioniert? Sorry für den schlechten Code, ich bin müde und danke im Voraus.
EDIT: Hier ist die find_normal Funktion Hier sind die Parameter:
@param pt_cl is a pointer to the point cloud to be treated (pcl::PointCloud<PointXYZRGB>::Ptr)
@param cloud_it is an iterator of this cloud (pcl::PointCloud<PointXYZRGB>::iterator)
@param kdt is the kd_tree used to find the closest neighbours of a point
@param radius defines the range in which to search for the neighbours of a point
@param max_neighbs is the maximum number of neighbours to be returned by the radius search
// auxilliary vectors for the k-tree nearest search
std::vector<int> pointIdxRadiusSearch; // neighbours ids
std::vector<float> pointRadiusSquaredDistance; // distances from the source to the neighbours
// the vectors of which the cross product calculates the normal
geom::vectors::vector3 *vect1;
geom::vectors::vector3 *vect2;
geom::vectors::vector3 *cross_prod;
geom::vectors::vector3 *abs_cross_prod;
geom::vectors::vector3 *normal;
geom::vectors::vector3 *normalized_normal;
// vectors to average
std::vector<geom::vectors::vector3> vct_toavg;
// if there are neighbours left
if (kdt.radiusSearch(*cloud_it, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance, max_neighbs) > 0)
{
for (int pt_index = 0; pt_index < (pointIdxRadiusSearch.size() - 1); pt_index++)
{
// defining the first vector
vect1 = geom::vectors::create_vect2p((*cloud_it), pt_cl->points[pointIdxRadiusSearch[pt_index + 1]]);
// defining the second vector; making sure there is no 'out of bounds' error
if (pt_index == pointIdxRadiusSearch.size() - 2)
vect2 = geom::vectors::create_vect2p((*cloud_it), pt_cl->points[pointIdxRadiusSearch[1]]);
else
vect2 = geom::vectors::create_vect2p((*cloud_it), pt_cl->points[pointIdxRadiusSearch[pt_index + 2]]);
// adding the cross product of the two previous vectors to our list
cross_prod = geom::vectors::cross_product(*vect1, *vect2);
abs_cross_prod = geom::aux::abs_vector(*cross_prod);
vct_toavg.push_back(*abs_cross_prod);
// freeing memory
delete vect1;
delete vect2;
delete cross_prod;
delete abs_cross_prod;
}
// calculating the normal
normal = geom::vectors::vect_avg(vct_toavg);
// calculating the normalized normal
normalized_normal = geom::vectors::normalize_normal(*normal);
// coloring the point
geom::aux::norm_toPtRGB(&(*cloud_it), *normalized_normal);
// freeing memory
delete normal;
delete normalized_normal;
// clearing vectors
vct_toavg.clear();
pointIdxRadiusSearch.clear();
pointRadiusSquaredDistance.clear();
// shrinking vectors
vct_toavg.shrink_to_fit();
pointIdxRadiusSearch.shrink_to_fit();
pointRadiusSquaredDistance.shrink_to_fit();
}
Ich denke, dass die Verwendung von Threads, wie Sie es mit Boost getan haben, für diese Aufgabe übertrieben ist. Werfen Sie einen Blick auf OpenMP und ähnliche Bibliotheken (Cilk, TBB). – iksemyonov
Außerdem sieht es so aus, als müssten Sie das gewünschte Ergebnis besser definieren. Im Moment ist es nicht ganz klar, ob Sie alle Punkte unabhängig und parallel verarbeiten wollen oder ob es ein bestimmtes Muster gibt, wenn Sie die Funktion auf Punkte anwenden ("die gleiche Funktion an zwei Punkten aufrufen"). – iksemyonov
ist es, es funktioniert definitiv nicht. Ich habe von TBB gehört, bin mir aber nicht sicher, ob es mit meiner Punktwolke funktioniert. Ich werde es versuchen, danke. –