繁体   English   中英

并行嵌套循环中OpenMP和做的内循环有更多话题

[英]parallelize nested loop in OpenMP and do inner loop with more thread

我有这种嵌套循环:我想知道如何以最佳形式并行化它,其中:

  1. 第二和第三for也是第五和第六for在同一时间运行

  2. 第一和第四for串行

如果我有24个内核,并希望为螺纹16之间划分外,并利用它们的其余部分执行内for他们,例如执行第二次for 8线程不是只有一个线程,我该怎么办?

void main()
{
//first_for
   for(int y=0; y< height; y++)
{
      //second_for 
      for(int x=0; x< width-1; x++)
   {
     func1();
   }
      //third_for
      for(int x=0; x< width-1; x++)
   {
     func2();
   }

}
//fourth_for
   for(int x=0; x<width; x++)
{
     //fifth_for
     for(int y=0; y< height-1; y++)
   {
     func3();
   }
     //sixth_for
     for(int y=0; y< height-1; y++)
   {
     func4();
   }
}
}

关于并行性介绍,通常会说越粗糙的级别越好,因此,如果您可以在可以扩展的粗糙级别添加并行指令,那么为什么还要添加嵌套并行性呢?

因此,根据可以同时运行的内容,我将这样编写main:

int main()
{
     //first_for
     #pragma parallel for
     for(int y=0; y< height; y++)
     {
          //second_for and third_for
      for(int x=0; x< width-1; x++)
     {
          func1();
          func2();

      }
  }
 //fourth_for
 #pragma parallel for
 for(int x=0; x<width; x++)
 {
      //fifth_for and  //sixth_for
     for(int y=0; y< height-1; y++)
    {
          func3();
          func4();
     }
  }
 return 0;
}
  1. 我们通过合并2个内部循环来增加每行每列的工作量

  2. 我们添加了openMP指令,以根据内核数量将计算循环拆分为较小的块。

  3. 看看是否可以反转第一个循环,因为取决于内部操作以及“图像”在内存中的映射方式,因此首先处理列可能会导致很多缓存错误。

编辑

您可以启用嵌套并行性,但是这样做的方式是错误的,过多的循环和线程访问不同块的内存只会降低性能,并且您还将为24核设计解决方案,而该解决方案可能无法与32、48核等进行扩展...但是,如果您坚持要设置环境变量或调用openMP函数:

 call omp_set_nested()
 or
 set OMP_NESTED=TRUE|FALSE

在顶级循环上添加openMP子句以指定后,指定仅用于X线程的块大小。

int  chunckSize = height / X;
#pragma parallel for schedule ( static , chunckSize)

openMP线程小组应该由24个线程组成,但是通过这样做,只有X可以完成工作。 遵循该逻辑进行嵌套循环。

但这不是我推荐的解决方案!

除了已经说过的内容,您可能还想显式启用嵌套并行性。 可以通过在运行时调用库或使用环境变量(对于OpenMP)来实现。

有关更多信息,请查看此Oracle Docs

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM