【问题标题】:openmp parallel sections within omp parallel for?omp并行内的openmp并行部分?
【发布时间】:2013-03-04 17:47:41
【问题描述】:

我有一个使用 OpenMP 并行化的外部 for 循环。然而,在这个 for 循环中,有一些代码也可以并行执行。

我可以使用 OpenMP 的sections 子句来并行化吗?这甚至可能吗?由于 for 循环的每次迭代仅由一个线程运行,我可以(在每次迭代中)要求某些代码部分由多个线程并行运行吗?其余代码应仅由一个线程运行,即该循环迭代已分配到的线程。

例如。我有以下代码:

omp_p = omp_get_max_threads();
omp_set_nested(1);
#pragma omp parallel for num_threads(omp_p/2)
for(int p=0;p<omp_p/2;p++){
   size_t a = (p*N)/(omp_p/2);
   size_t b = ((p+1)*N)/(omp_p/2);
   for(int i=a;i<b;i++){
      /*Work on A[a]->A[b]*/
      for(int j=0;j<n;j++){
         for(int k=0;k<N;k++){
           /*Serial code*/
          #pragma omp parallel sections
              {
                 #pragma omp section
                   {

                   }
                 #pragma omp section
                   {

                   }

              }
           /*Serial work*/
           #pragma omp parallel sections
              {
              #pragma omp section
                   {

                   }
                 #pragma omp section
                   {

                   }
              }
           /*Serial code*/
         }
      }
   }
}

这会导致程序运行得比我根本不使用并行部分要慢得多..

【问题讨论】:

  • 除了嵌套并行的巨大开销之外,您的ijk 循环计数器获得shared 的默认共享类,并且应该显式声明private。跨度>
  • 哦,对不起,我忘了在 for() 大括号中将它们声明为整数。更正了这个..
  • 是什么阻止您简单地分解所有线程之间的循环并串行执行内部循环中的所有内容?与线程数相比,N 是否太低?
  • 这就是我编写它的方式,但我意识到除了一些分配(需要串行完成)之外,最里面的“k”循环主要有两个可以并行执行的大部分。它类似于矩阵乘法代码,矩阵在线程之间划分,大部分工作发生在最内层循环中。所以我想知道是否应该为每个线程提供更大的矩阵块并保留两个线程(每个线程)以并行执行最内层循环中的操作。 N ~ 5*omp_p
  • OpenMP 与大多数其他并行编程范式一样,引入了同步开销,因此它支持计算模型,其中每个线程尽可能多地工作并尽可能少地同步。您的实现未充分利用线程,因为在嵌套并行之外存在串行部分,其中第二个线程什么都不做。移除嵌套的并行性,让外循环使用所有线程,然后针对错误共享等情况分析代码。

标签: openmp


【解决方案1】:

嵌套 OMP 应该是可能的。但我担心由于以下原因,您可能看不到任何性能提升:

  1. 嵌套 OMP 可能会导致生成的线程数多于 CPU 内核数。这可能会导致大量的上下文切换。
  2. 您的 OMP 并行部分位于 4 个嵌套 for 循环的深处,因此,由于线程的创建和销毁可能会产生开销。

【讨论】:

  • 鉴于 OP 明确指示外部并行区域以配置的线程数的一半运行,并且每个 sections 构造只有两个部分,因此您的第一点无效。
  • @HristoIliev 给定节数而不设置 num_threads(),创建的 omp 线程数是否等于节数?如果是,对不起,那我不知道..
  • 对不起,很明显我误读了您文本中的模态。有多少线程将用于具有两个部分的组合区域,具体取决于实现。
  • 在并行子句中设置 num_threads(2) 没有帮助。所以我猜减速主要是由于嵌套并行?
猜你喜欢
  • 1970-01-01
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 2012-05-19
相关资源
最近更新 更多