2016-12-15 3 views
0

を実行する:私の問題は、私はアルゴリズムで合計をやっているとき、ある、それは多くの時間を取ってパラレルIは下の画像をアルゴリズムを実装しようとしている悪い

Image of Algorithm

。してください、私は間違って何をしていますか?

Parallel.For(0, n, i => 
{ 
    Parallel.For(0, n, j => 
    { 
     double sum1 = 0; 
     double sum2 = 0; 
     if (i > j) 
     { 
      for (int a = 1; a < j - 1; a++) 
      { 
       sum1 = sum1 + (matrixL[i, a] * matrixU[a, j]); 
      } 

      matrixL[i, j] = (matrixA[i, j] - sum1)/matrixU[j, j]; 
     } 
     else 
     { 
      for (int a = 1; a < i - 1; a++) 
      { 
       sum2 = sum2 + (matrixL[i, a] * matrixU[a, j]); 
      } 
      matrixU[i, j] = matrixA[i, j] - sum2; 
     } 
    });    
}); 
+1

プロファイラを使ってみましたか? –

+3

Parallel.Forの使用によるオーバーヘッドは、両方のループで使用するには多すぎるかもしれません。擬似コードは内部ループが並列であることのみを指定しています。 –

+2

あなたは、時間がかかっていると思われるものにちょっとした文脈を与えることができますか? – juharr

答えて

1

ここにはいくつかの項目があります。

まず、@MalteRがコメントに示されているように、擬似コードは外部ループが並列でなければならないとは言いません。私はこれを行うことが実際に受け入れられるかどうかについて矛盾することを読んだ。 Microsoftのthis blog postは、 "入れ子になった" Parallel.Forループを持つことは問題ないと言っていますが、パフォーマンスを低下させるという不満を持っている他のStack Overflowの質問(this oneなど)を見てきました。

Parallel.For(0, n, i => 
{ 
    Parallel.For(0, n, j => 
    { 

ではなく

for (int i = 0; i < n; i++) 
{ 
    Parallel.For(0, n, j => 
    { 

あなたが実際に並列化から得ることができますどのくらいのハードリミットがあることに注意してくださいを:今あなたが持っている、明確にする

。マシンは一度に有限個のものしか実行できません(xと呼んでください)。したがって、CPUバインドされたタスクでx以上のものを一度に処理しようとすると、実際にはパフォーマンスは向上しません。

これを少し試して、私がリンクしている記事を見て、外部のParallel.Forループがあなたのパフォーマンスを助けているかどうかを調べることができます。

大きな最適化は、擬似コードではコンバージェンスまでループするように指定していますが、実際には必要ない場合でも常にループn回ループすることが擬似コードに記載されています。だからあなたは次のようなことをすることができます:

for (int i = 0; i < n; i++) 
{ 
    Parallel.For(0, n, j => 
    { 
     // Do the algo 
    } 

    if ([test for convergence]) { 
     break; // No need to keep going 
    } 
} 
+0

説明ありがとう、私はそれを探しています。 – Oneteil

+2

擬似コードは、内側のための外側と並列のループのための通常のループを持っていますが、私は周りの他の方法が速くなると思う。より短い反復ではなく、より短い反復を使用して並列処理から多くを得ることができます。もちろん、相対的なサイズに応じてトレードオフポイントがあります。 – nurdyguy

+1

あなたが書いたように最初のステップを変更しました。アルゴリズムは1000x1000の要素に対して2500msを要します。 – Oneteil

関連する問題