1

コードは、圧縮された列ストレージに格納されたスパース行列と列ベクトルの乗算です。1 つ目はシリアル コードです。2 つ目はオープン cl カーネルです。inputimage と output の代わりに、より意味のある名前を使用させてください。

コードを並列化する必要がありました.シリアル出力はカーネルの出力とは異なります.誰かが私に欠けているものを教えてもらえますか?

シリアルコードは

int result[4]={0,0,0,0};
   for(int col=0;col<4;col++)
     {
         for(int j=rowptr[col];j<rowptr[col+1];j++)
         {

         result[index[j]]+=val[j]*colvector[col];

         }
     }

その出力は、並列コードとは異なります。カーネルあたりのワーク ユニットは 4 に設定されています。並列コードを以下に示します。誰か、何が欠けているか教えてください。

      int col=get_global_id(0);

  for(int j=rowptr[col];j<rowptr[col+1];j++)
         {

         result[index[j]]+=val[j]*colvector[col];

         }
4

1 に答える 1

3

OpenCL では、4 つの作業項目が並行して実行されます。それらはすべてoutput2[inputImage4[j]]同時に更新しようとします。動作は未定義ですが、4 つの作業項目のうちの 1 つのみの貢献が見られるでしょう。

この種の問題を解決するには、アルゴリズムを変更するか、値に頻繁にアクセスしない場合はアトミック操作 (更新をシリアル化します) を使用する必要があります。

于 2012-09-11T21:40:03.010 に答える