是否有可能评估OpenMP开销成本?

时间:2015-02-25 07:24:40

标签: c openmp

我正在尝试使用OpenMP优化有关图像处理的代码。我仍在学习它,我来到经典的并行for循环,这比我的单线程实现要慢。

我尝试并行化的for循环只有50次迭代,我看到它解释了为什么OpenMP在这种情况下使用由于开销操作而无用。

但是有可能评估这些成本吗?共享/私有/ firstprivate(...)子句之间的成本差异是什么?

这是我要并行化的for循环:

#pragma omp parallel for \
      shared(img_in, img_height, img_width, w, update_gauss, MoGInitparameters, nb_motion_bloc) \
      firstprivate(img_fg, gaussStruct) \
      private(ContrastHisto, j, x, y) \
      schedule(dynamic, 1) \
      num_threads(max_threads) 
  for(i = 0; i<h; i++){ // h=50
    for(j = 0; j<w; j++){
      ComputeContrastHistogram_generic1D_rect(img_in,  H_DESC_STEP*i, W_DESC_STEP*j, ContrastHisto, H_DESC_SIZE, W_DESC_SIZE, 2, img_height, img_width);
      x = i;
      y = w - 1 - j;
      img_fg->data[y][x] = 1-MatchMoG_GaussianInt(ContrastHisto, gaussStruct->gauss[i*w+j], update_gauss, MoGInitparameters);;
      #pragma omp critical
      {
        nb_motion_bloc += img_fg->data[y][x];
        nb_motion_bloc += img_fg->data[y][x];
      }
    }
  }

也许我犯了一些错误,但如果是这样,请告诉我原因!!

1 个答案:

答案 0 :(得分:2)

有几点不能解决您的具体问题。

尽量避免使用#pragma omp critical。在这种情况下,您可以通过向reduction(+:nb_motion_bloc )行添加omp parallel for子句并使用nb_motion_bloc += 2*img_fg->data[y][x];来完全删除它。

根据每次迭代需要做多少工作,短循环会产生(更多)更多的开销,而不是它们的价值。

现在回答问题。如果您没有更改任何变量,请不要将它们分类为shared / private / firstprivate。如果它们应该被每个线程使用并丢弃,你可以使用像

这样的结构
#pragma omp parallel
{
    int x, y;
    #pragma omp for
    for(i = 0; i<h; i++)
    {
        ...
    }    
}

如果工作负载达到平衡,请考虑使用schedule(static)

关于shared / private / firstprivate之间的差异,请参阅thisthis个问题。来自wikipedia

  
      
  • shared:并行区域内的数据是共享的,这意味着所有线程同时可见并可访问。默认情况下,工作共享区域中的所有变量都是共享的,但循环迭代计数器除外。
  •   
  • private:并行区域内的数据对每个线程都是私有的,这意味着每个线程都有一个本地副本并将其用作临时变量。未初始化私有变量,并且不维护该值以在并行区域之外使用。默认情况下,OpenMP循环结构中的循环迭代计数器是私有的。
  •   
  • default:允许程序员声明并行区域中的默认数据范围将是共享的,或者对于C / C ++是无共享的,或者对于Fortran是共享的,firstprivate的,private的,或者是none。 none选项强制程序员使用数据共享属性子句声明并行区域中的每个变量。
  •   
  • firstprivate:喜欢私有,除了初始化为原始值。
  •   
  • lastprivate:与private相同,但在构造之后更新原始值。
  •