3

私は最近OpenMPについて読んでいて、スピードアップを得るためにプログラム内の既存のforループのいくつかを並列化しようとしていました。しかし、どういうわけか、ファイルにガベージデータが書き込まれているようです。つまり、ファイルにポイント1、2、3、4などが書き込まれておらず、ポイント1、4、7、8などがあります。これは、ポイント1、2、3、4などを追跡していないためだと思われます。スレッドとそれは競合状態につながるだけですか?

マルチスレッドプログラミングを行うことは素晴らしい抽象化のように思われるので、私はOpenMPについて見つけることができる限り多くを読んでいます。私が間違っているかもしれないことの根底に到達するために、どんなポインタでもお願いします。

これが私がこれまでにやろうとしてきたことです(関連するコードのビットのみ):

#include <omp.h>

pixelIncrement = Image.rowinc/2;

#pragma omp parallel for
for (int i = 0; i < Image.nrows; i++ )
   {
      int k =0;
      row     = Image.data + i * pixelIncrement;

      #pragma omp parallel for
      for (int j = 0; j < Image.ncols; j++)
      {
          k++; 
          disparityThresholdValue = row[j];  
                 // Don't want to save certain points
             if ( disparityThresholdValue < threshHold)
             {       
                // Get the data points
                x = (int)Image.x[k]; 
                y = (int)Image.y[k]; 
                z = (int)Image.z[k]; 
                grayValue= (int)Image.gray[k];      

                cloudObject->points[k].x = x;
                cloudObject->points[k].y = y;
                cloudObject->points[k].z = z;
                cloudObject->points[k].grayValue = grayValue;

        fprintf( cloudPointsFile, "%f %f %f %d\n", x, y, z, grayValue);
             }
      }
   }

   fclose( pointFile );

コンパイラー設定(C /C++->言語->OpenMPサポート(/ openmp))でOpenMPを有効にしました。

何が問題になるのかについて何か提案はありますか?WindowsXP32ビットでクアッドコアプロセッサを使用しています。

4

3 に答える 3

3

すべてのポイントがファイルに書き込まれていますが、順次ではありませんか、それとも実際のポイント データがめちゃくちゃですか?

最初のケースは、並列プログラミングで予想されます。何かを並べて実行すると、アクセスを同期しない限り、順序を保証できなくなります (その時点で、並列化は実質的に線形になるため、並列化を省略できます)。順序に依存する必要がある場合は、任意の計算を並列化できますが、1 つのスレッドに書き留める必要があります。

ポイント自体が台無しになっている場合は、変数が宣言されている場所と、複数のスレッドが同じものにアクセスしているかどうかを確認してください。

于 2012-08-20T22:00:23.123 に答える
3

ここにいくつかの問題があります:

#pragma omp parallel for
for (int i = 0; i < Image.nrows; i++ )
   {
      int k =0;
      row     = Image.data + i * pixelIncrement;

      #pragma omp parallel for
      for (int j = 0; j < Image.ncols; j++)
      {
          k++; 

インナーは不要ですparallel for。外側のループには、すべてのコアをビジー状態に保つのに十分な作業が含まれている必要があります。

また、内側のループkは共有変数であり、非アトミックな方法でインクリメントされます。xyzも内側のループ スレッド間で共有され、「ランダムに」上書きされます。内部ディレクティブを削除して、様子を見てください。

于 2012-08-21T05:31:12.080 に答える
0

ネストされたループを含むループがある場合、2 番目の omp プラグマは必要ありません。最初のループはすでに並列化されています。これは、2 番目のループを順番に実行する必要がある場合にのみ有効であることに注意してください。順次インクリメントがあるため、2 番目のループをランダムな順序で実行することはできません。OMP プラグマは、コードを並列化するための非常に簡単でクールな方法ですが、あまり使用しないでください。

詳細はこちら -> OpenMP による並列ループ

于 2014-06-15T17:18:07.797 に答える