我是并行编程的新手。我正在尝试使点云处理过程并行化。我在下面分享我的程序结构。首先,我将点云分为部分云。我的目标是每个线程必须分别调用fillFrustumCloud()函数。
int num_threads = 12;
std::vector<CloudColored::Ptr> vector_colored_projected_clouds(num_threads);
std::vector<Cloud::Ptr> vector_projected_clouds(num_threads);
omp_set_num_threads(num_threads);
// private( ) shared()
#pragma omp parallel shared(vector_colored_projected_clouds,vector_projected_clouds)
{
for(int i=0; i<num_threads; i++)
{
#pragma omp critical
{
std::cout << "Thread id: " << omp_get_thread_num() << " loop id: " << i << std::endl;
}
const unsigned int start_index = cloud_in->size()/num_threads*i;
const unsigned int end_index = cloud_in->size()/num_threads*(i+1);
Cloud::Ptr partial_cloud(new Cloud);
if(i==num_threads-1)
{
partial_cloud->points.assign(cloud_in->points.begin()+start_index, cloud_in->points.end());
}else{
partial_cloud->points.assign(cloud_in->points.begin()+start_index, cloud_in->points.begin()+end_index);
}
LidcamHelpers::fillFrustumCloud(partial_cloud, mat_point_transformer, img_size, vector_colored_projected_clouds,
vector_projected_clouds, i, interested_detections, id, reshaped_img);
}
}
但输出是:
Thread id: 0 loop id: 0
Thread id: 1 loop id: 0
Thread id: 2 loop id: 0
Thread id: 3 loop id: 0
Thread id: 0 loop id: 1
Thread id: 1 loop id: 1
Thread id: 2 loop id: 1
Thread id: 3 loop id: 1
Thread id: 0 loop id: 2
Thread id: 3 loop id: 2
Thread id: 2 loop id: 2
Thread id: 1 loop id: 2
Thread id: 3 loop id: 3
Thread id: 1 loop id: 3
Thread id: 2 loop id: 3
Thread id: 0 loop id: 3
根据我的目标,应该是这样的:
Thread id: 0 loop id: 0
Thread id: 1 loop id: 1
Thread id: 2 loop id: 2
请注意:为了存储结果,我通过引用将vector_colored_projected_clouds和vector_projected_clouds传递到函数中。我猜他们应该是共享变量。
该#pragma omp parallel
构造函数将创建一个并行区域,其中包含与设置它一样多的线程。因此,当你这样做时:
#pragma omp parallel
{
for(int i=0; i<num_threads; i++)
{
...
}
}
并行区域中的每个线程将执行循环的所有迭代。这就是为什么你有16条输出线(即4个线程x 4个循环迭代)的原因。
如果要在线程之间分配循环的迭代,则应使用#pragma omp for
。因此,在你的代码中,你可以执行以下操作:
#pragma omp parallel
{
#pragma omp for
for(int i=0; i<num_threads; i++)
{
...
}
}
或者
#pragma omp parallel for
for(int i=0; i<num_threads; i++)
{
...
}
由于你只想在线程之间分配循环的迭代,因此可以使用后者(即 #pragma omp parallel for
)。
好像你正在使用
#pragma omp critical
{
std::cout << "Thread id: " << omp_get_thread_num() << " loop id: " << i << std::endl;
}
用于调试目的。但是请记住,即使对于该critical
区域,线程输出的顺序也是不确定的。如果你希望线程将确定性地输出,请使用#pragma omp ordered
而不是critical。该ordered
构造函数将强制执行的代码块,它环绕将在会如果代码是顺序执行的已执行相同的顺序执行。