【问题标题】:OpenMP for loop with specific threads具有特定线程的 OpenMP for 循环
【发布时间】:2020-11-30 10:38:00
【问题描述】:

我是并行编程的新手。我正在尝试使点云处理过程并行。我在下面分享我的程序结构。首先,我将点云分成部分云。我的目标是每个线程都必须分别调用 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 传递到函数中,以便存储结果。我猜它们应该是共享变量。

【问题讨论】:

    标签: c++ multithreading performance parallel-processing openmp


    【解决方案1】:

    这个#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 而不是关键的。 ordered 构造函数将强制它包裹的代码块按照顺序执行的顺序执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-12
      • 2017-04-26
      • 1970-01-01
      • 2018-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多