0

OpenMP を使用してガウス消去法とピボットを並列化しようとしています。

以下は、私が書いたコードの関連セクションです。

struct timeval tvBegin, tvEnd;
gettimeofday(&tvBegin, NULL);

for (k=1; k<=n-1; ++k) {

 amax = (double) fabs(a[k][k]) ;
 m = k;
 for (i=k+1; i<=n; i++){   /* Find the row with largest pivot */
           xfac = (double) fabs(a[i][k]);
           if(xfac > amax) {amax = xfac; m=i;}
 }
 if(m != k) {  /* Row interchanges */
             rowx = rowx+1;
             temp1 = b[k];
             b[k]  = b[m];
             b[m]  = temp1;

             for(j=k; j<=n; j++) {
                   temp = a[k][j];
                   a[k][j] = a[m][j];
                   a[m][j] = temp;
             }
  }
    #pragma omp parallel for private(i,j)
    for (i=k+1; i<=n; ++i) {
      xfac = a[i][k]/a[k][k];

           for (j=k+1; j<=n; ++j) {
               a[i][j] = a[i][j]-xfac*a[k][j];
           }
      b[i] = b[i]-xfac*b[k];
   }                 matrix_print_off (n, n, a);}        

}

gettimeofday(&tvEnd, NULL);
printf("\nTime elapsed in ms: %d\n", diff_ms(tvEnd, tvBegin));

このコードを 1000*1000 マトリックスでテストしました。4 コア マシンでこのコードを実行するのにかかった平均時間 (diff_ms で測定) は、このコードのシーケンシャル バージョン (プラグマなし) と同じ (2142ms) でした。ここでは膨大な並列処理が行われているため、これは当てはまりません。どこが間違っていたのか教えてください。

参考までに、以下に diff_ms 関数も添付しました。

int diff_ms(struct timeval t1, struct timeval t2)
{
    return (((t1.tv_sec - t2.tv_sec) * 1000) + 
        (t1.tv_usec - t2.tv_usec)/1000);
}

ありがとう!

4

1 に答える 1

1

並列セクション内には、 がありますmatrix_print_off()。print 関数がスレッド セーフであると仮定すると、達成できる並列処理の量が大幅に減少します。さらに、matrix_print_off()ブロッキング IO を使用する場合、この関数の時間が関数の残りの部分を支配する可能性があります。

于 2013-02-23T17:21:53.917 に答える