OpenMP - 并行嵌套循环

时间:2012-05-23 09:53:42

标签: c++ multithreading openmp

我遇到了尝试重新编码嵌套for循环以便并行化的问题:

for(i=0; i<n; i++)
{
    for(j=0; j<n; j++)
    {
        if(asubsref(struct1,j) > 0)
            asubsref(struct2,j) = asubsref(struct3,j) + 1;
    }
    for(j=0; j<n; j++)
        asubsref(struct1,j) = asubsref(struct2,j) - asubsref(struct3,i);
}

Struct1 / struct2是两个分别带有width / height / int-float数组的结构。 struct3是一个float结构。

我到目前为止的尝试是将它们分成两个不同的循环但是唉,它没有用,因为我得到了很多不正确的结果:

#pragma omp parallel
{
#pragma omp for private(j)
   for(i=0; i<n; i++)
   {
     for(j=0; j<n; j++)
     {
       if(asubsref(struct1,j) > 0)
         asubsref(struct2,j) += 1;
     }
   }
#pragma omp for private(j)
   for(i=0; i<n; i++)
   {
     k = asubsref(struct3,i);
     for (j=0; j<n; j++)
     {
       asubsref(struct1,j) -= k;
     }
   }
}

我不是在寻找答案,而是一些指导,帮助我思考如何解决这个问题/提示答案等。

1 个答案:

答案 0 :(得分:4)

我在这段代码中看到的是三个数组:

array1: asubsref(seed,0) ... asubsref(seed,n-1)
array2: asubsref(bin,0) ... asubsref(bin,n-1)
array3: asubsref(w,0) ... asubsref(w,n-1)

如果这个假设是正确的并且asubsref不产生任何副作用,则可以导出以下不变量:

  

循环执行结束后,array2 [j]递增   数字x是最大数字,使得array3 [i]之和   对于从0到x的i小于array1 [j]。

这是你能做的。首先,你可以合并两个最里面的循环,因为(在我们的假设下)它们的迭代是独立的:

for(i=0; i<n; i++)
{
    for(j=0; j<n; j++)
    {
        if(asubsref(seed,j) > 0)
            asubsref(bin,j) = asubsref(bin,j) + 1;
        asubsref(seed,j) = asubsref(seed,j) - asubsref(w,i);
    }
}

然后交换最里面和最外面的循环

for(j=0; j<n; j++)
{
   for(i=0; i<n; i++)
   {
        if(asubsref(seed,j) > 0)
            asubsref(bin,j) = asubsref(bin,j) + 1;
        asubsref(seed,j) = asubsref(seed,j) - asubsref(w,i);
   }
}

现在很明显,以下代码应该可以正常工作

#pragma omp parallel for (private i)
for(j=0; j<n; j++)
{
   for(i=0; i<n; i++)
   {
        if(asubsref(seed,j) > 0)
            asubsref(bin,j) = asubsref(bin,j) + 1;
        asubsref(seed,j) = asubsref(seed,j) - asubsref(w,i);
   }
}

虽然分裂循环明显打破了不变量。