0

Recently I started using OpenMP. Doing a numerical calculation involving 3d matrices created in c++ as vectors and I used parallel for loops to speedup the code. But it runs slower than serial code. I compile the code using Codeblocks in Windows 7. The code is something like this.

int main(){
  vector<vector<vector<float> > > Dx; //

/*create 3d array Dx[IE][JE][KE] as vectors*/
  Dx.resize(IE);
  for (int i = 0; i < IE; ++i) {
    for (int j = 0; j < JE; ++j){
      dx[i][j].resize(KE);
    }
  }
  //declare and initialize more matrices like this
  .
  .
  .
  double wtime = omp_get_wtime(); // start time
  //and matrix calculations using parallel for loop 

  #pragma omp parallel for
  for (int i=1; i < IE; ++i ) {
    for (int j=1; j < JE; ++j ) {
      for (int k=1; k < KE; ++k ) {
        curl_h = ( Hz[i][j][k] - Hz[i][j-1][k] - Hy[i][j][k] + Hy[i][j][k-1]);
        idxl[i][j][k] = idxl[i][j][k] + curl_h;
        Dx[i][j][k] = gj3[j]*gk3[k]*dx[i][j][k] 
                    + gj2[j]*gk2[k]*.5*(curl_h + gi1[i]*idxl[i][j][k]);
      }  
    }
  }

  wtime =  omp_get_wtime() - wtime;
}

But code with parallel loops run slower than the serial code. Any ideas ? Thxs.

4

1 に答える 1

0

ループは変数 を使用しますcurl_hが、これはスレッド プライベートとして宣言されていません。これはバグであり、認識されたパフォーマンスの問題の理由でもあります。

curl_hが格納されるメモリ内の場所は 1 つだけであるため、すべてのスレッドが常に同時に読み書きを試みます。1 つの CPU コアがそのキャッシュに値をロードし、次の CPU コアがそれに書き込みを発行して、最初の CPU のキャッシュを無効にし、それ自体が使用しようとするとキャッシュラインを再び取得しますcurl_h(読み取りまたは書き込み、どちらもキャッシュラインがローカル キャッシュにあることを確認します)。

要点は、ハードウェアが 1 つしかメモリ ロケーションを呼び出さないという激しいふりをすることで、curl_hそのトリビュートが要求されるということです。キャッシュ コヒーレンシ プロトコルで膨大な量のおしゃべりが発生し、メモリから同じキャッシュラインを絶えず再フェッチすることでメモリ バスをビジー状態に保ちます。スレッドが実際に行っていることは、その 1 つのキャッシュラインをめぐって争っていることです。

もちろん、スレッド間の絶え間ない競合は大きなバグです。現在使用している値が実際に上記のステートメントで計算した値であると確信できるプロセスはありません。

したがって、ステートメントに正しいprivate()宣言を追加するだけomp parallel forで、バグとパフォーマンスの問題の両方を修正できます。

于 2017-02-01T13:26:10.587 に答える