嵌套的openmp循环

时间:2013-11-06 16:56:52

标签: c++ parallel-processing openmp

我有一段以下风格的代码:

for (set=0; set < n; set++)  //For1
{
   #pragma omp parallel for num_threads(x)
    for (i=0; i < m; i++)   //For2: this loop can be executed in parallel
   {
      commands...
   }

   for (j=0; j < m; j++)   //For3: this loop depends on the output of the For2 and also should be executed in a sequential way
   {
     commands...
   }

}

正如您所注意到的,我有n个独立的集合(外部循环,即For1)。每个Set包含一个并行循环(For2)和一个顺序部分(For3),它应该在For2之后执行。

我已经为For2使用了“#pragma omp parallel for num_threads(x)”来使其并行。

现在我想让外环(For1)平行。换句话说,我想并行运行每个Set。

如果你能告诉我openmp中的可能性,我真的很感激。

一种方法可能是创建与每个Set对应的n个线程。这是对的吗?但我想知道是否有另一种方法完全使用openmp功能?

提前感谢。

3 个答案:

答案 0 :(得分:1)

您可以通过

简单地并行外循环
#pragma omp parallel for num_threads(x) private(i,j)
for (set=0; set < n; set++)  //For1
{
    for (i=0; i < m; i++)   //For2: this loop can be executed in parallel
   {
      commands...
   }

   for (j=0; j < m; j++)   //For3: this loop depends on the output of the For2 and also should be executed in a sequential way
   {
     commands...
   }

}

答案 1 :(得分:0)

您可以尝试融合第一个和第二个循环(见下文)。我不知道这是否会让它变得更好但是值得一试。

    #pragma omp parallel num_threads(x) private(set, i)
    {
        #pragma omp for schedule(static)
        for (k = 0; k < n*m; k++) //fused For1 and For2
        {
            set = k/m;
            i = k%m;
            //commands...
        }
        #pragma omp for schedule(static)
        for (set = 0; set < n; set++)
        {
            for (i = 0; i < m; i++) //For3 - j is not necessary so reuse i 
            {
                //commands...
            }
        }
    }

答案 2 :(得分:0)

根据您拥有的套数,简单地并行化外循环可能是您的最佳选择。如果您的计算机上有多个核心数,那么它可能比并行化内部循环更快,因为在这种情况下,线程创建开销要少得多。

假设您的操作是cpu绑定的,并且外部循环并行化,您将完全使用计算机上的所有核心。如果所有资源都已经使用,那么进一步尝试并行化内部循环将不会更快。

如果您的设置数少于可用内核,则内部循环并行化,您很可能已经消耗了所有可用的计算能力。

如果你真的想要并行化两个循环,那么你应该考虑MPI并在几台计算机上进行混合并行化;外部循环在几台计算机上并行化,内部循环在一台计算机的所有核心上并行化。