Adi程序与openmp

时间:2015-02-12 01:09:26

标签: c openmp

这是我在这里的第一篇文章,如果我提出一个简单/愚蠢的问题,那就很抱歉。我有一个并行编程类的任务。我需要一些程序来并行化。所以我的问题如下;我无法并行化程序的所有部分。如果我并行化2个for块,则结果与串行结果不同。所以这是程序

#pragma scop
 for (t = 0; t < _PB_TSTEPS; t++)
    {
#pragma omp parallel for schedule(dynamic) shared(X,B,A)  private(i1,i2) 
      for (i1 = 0; i1 < _PB_N; i1++)
    for (i2 = 1; i2 < _PB_N; i2++)
      {
        X[i1][i2] = X[i1][i2] - X[i1][i2-1] * A[i1][i2] / B[i1][i2-1];
        B[i1][i2] = B[i1][i2] - A[i1][i2] * A[i1][i2] / B[i1][i2-1];
      }
#pragma omp parallel for schedule(dynamic) shared(X,B)  private(i1)
      for (i1 = 0; i1 < _PB_N; i1++)
    X[i1][_PB_N-1] = X[i1][_PB_N-1] / B[i1][_PB_N-1];
#pragma omp parallel for schedule(dynamic) shared(X,B,A)  private(i1,i2) 
      for (i1 = 0; i1 < _PB_N; i1++)
    for (i2 = 0; i2 < _PB_N-2; i2++)
      X[i1][_PB_N-i2-2] = (X[i1][_PB_N-2-i2] - X[i1][_PB_N-2-i2-1] * A[i1][_PB_N-i2-3]) / B[i1][_PB_N-3-i2];

      for (i1 = 1; i1 < _PB_N; i1++)
    for (i2 = 0; i2 < _PB_N; i2++) {
      X[i1][i2] = X[i1][i2] - X[i1-1][i2] * A[i1][i2] / B[i1-1][i2];
      B[i1][i2] = B[i1][i2] - A[i1][i2] * A[i1][i2] / B[i1-1][i2];
    } 
#pragma omp parallel for schedule(dynamic) shared(X,B)  private(i2)
      for (i2 = 0; i2 < _PB_N; i2++)
    X[_PB_N-1][i2] = X[_PB_N-1][i2] / B[_PB_N-1][i2];

      for (i1 = 0; i1 < _PB_N-2; i1++)
    for (i2 = 0; i2 < _PB_N; i2++)
      X[_PB_N-2-i1][i2] = (X[_PB_N-2-i1][i2] - X[_PB_N-i1-3][i2] * A[_PB_N-3-i1][i2]) / B[_PB_N-2-i1][i2];
    }
#pragma endscop

我必须对代码的这一部分进行并行化,我无法弄清楚如何并行化上面的for和另外两个for。我尝试了大致相同的openmp代码与其他for&#39; s。以下是我遇到问题的两个for块。

  for (i1 = 1; i1 < _PB_N; i1++)
    for (i2 = 0; i2 < _PB_N; i2++) {
      X[i1][i2] = X[i1][i2] - X[i1-1][i2] * A[i1][i2] / B[i1-1][i2];
      B[i1][i2] = B[i1][i2] - A[i1][i2] * A[i1][i2] / B[i1-1][i2];
    } 



for (i1 = 0; i1 < _PB_N-2; i1++)
    for (i2 = 0; i2 < _PB_N; i2++)
      X[_PB_N-2-i1][i2] = (X[_PB_N-2-i1][i2] - X[_PB_N-i1-3][i2] * A[_PB_N-3-i1][i2]) / B[_PB_N-2-i1][i2];
    }

提前谢谢。

查看此处的所有代码,

https://github.com/fedon99/Stack-Overflow/blob/master/adi.c

1 个答案:

答案 0 :(得分:0)

行的值取决于其他行,因此您无法轻松并行化。但是,列不依赖于其他列,因此您可以像这样并行化内部循环:

for (i1 = 1; i1 < _PB_N; i1++)
    #pragma omp parallel for
    for (i2 = 0; i2 < _PB_N; i2++) {
      X[i1][i2] = X[i1][i2] - X[i1-1][i2] * A[i1][i2] / B[i1-1][i2];
      B[i1][i2] = B[i1][i2] - A[i1][i2] * A[i1][i2] / B[i1-1][i2];
    }
} 

for (i1 = 0; i1 < _PB_N-2; i1++) {
    #pragma omp parallel for
    for (i2 = 0; i2 < _PB_N; i2++) {
        X[_PB_N-2-i1][i2] = (X[_PB_N-2-i1][i2] - X[_PB_N-i1-3][i2] * A[_PB_N3-i1][i2]) / B[_PB_N-2-i1][i2];
    }
}

只要_PB_N >> nthreads这应该可以正常工作。

你也可以像这样交换循环的顺序

#pragma omp parallel for private(i1)
for (i2 = 0; i2 < _PB_N; i2++) {
    for (i1 = 1; i1 < _PB_N; i1++)

然而,这将是缓存不友好。

此外,我认为没有任何理由使用动态调度。静态调度应该更有效。如果你没有指定调度(就像我上面的代码那样),事实上的默认值是静态的。