4

質問があります。入れ子並列性能質問

別のParallel.ForEachの中にParallel.Invokeを使用することのメリットはありますか?ここで

は私のコードです:

Parallel.ForEach(yearMonths, 
        () => new List<DJVSStatsCo>(), 
        (yearMonth, loopState, localDjvsStatsCo) => 
         { 
          var coVintageCounter = 0; 
          var coExitsCounter = 0; 
          var coExtant = 0; 

          Parallel.Invoke(() => 
              coVintageCounter = globalData.ValuationEventsPit. 
                    Where(x => x.FirstRoundYearMonth <= yearMonth). 
                    Select(x => x.CompanyId).Distinct().Count(), 
              () => 
              coExitsCounter = globalData.ValuationEventsPit. 
                    Where(x => x.ExitDate != null && x.ExitDateYearMonth == yearMonth). 
                    Select(x => x.CompanyId).Distinct().Count(), 
              () => 
              coExtant = globalData.ValuationEventsPit. 
                  Where(x => x.FirstRoundYearMonth <= yearMonth && (x.ExitDate == null || x.ExitDateYearMonth > yearMonth)). 
                  Select(x => x.CompanyId).Distinct().Count() 
           ); 

          localDjvsStatsCo.Add(new DJVSStatsCo(yearMonth, coVintageCounter, coExtant, coExitsCounter)); 

          return localDjvsStatsCo; 
         }, 
        x => 
         { 
          lock (locker) 
          { 
           djvsStatsCos.AddRange(x); 
          } 
         }); 

私はおよそ50Kレコードを持っているし、私のマシンは、2つのコアプロセッサを持っていると私は、ほぼ同じ結果を得ていますカルク時間を計算します。だから私の質問は、ParallelをParallelの中に使用することのメリットはあるのだろうか?これのベストプラクティスは何ですか?

ありがとうございます。

よろしくお願いいたします。 Vlad。

+1

両方のケースで同じスループットを得るなら、 'Parallel.Invoke'でコードを複雑にする理由はありません。言い換えれば、* less * parallelがすでにCPUを飽和させている場合は、*より多くの*並列を作るためのボーナスポイントは得られません。ポイントを失うことさえあります! –

答えて

5

この場合、(おそらく)はありません。 は、「外側」の仕事は比較的少ないが潜在的に「内部」の仕事が多い場合に役立ちます。

一方、これらの3つのジョブが何をしているかによっても異なります。並列に実行できる本質的に非同期タスク(データベースなど)の場合は、確かに... ローカル CPU集約型タスクの場合は、おそらく追加作業を実際の利益のためのスケジューラー。すでに外側のループの並列化以来、コードの見た目を考えると

、それはあなたが恐らく単一のクエリ(または多分3)を行うことから利益を得ることができることを私を打つといえyearMonthによってグループ化...

4

あなたのCPUがビジー状態(50k個の要素)を維持しているので、並列処理を導入する際の利点はほとんどありません以内にループを入れてください。わかりやすくするために、コードを簡略化するためにParallel.Invoke呼び出しを削除します。

+1

サブタスクが純粋に計算的であると仮定します。 –