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'使代碼複雜化。換句話說,如果*少*並行已經使CPU飽和,你就不會得到獎勵積分*有時你甚至會失分! –

回答

5

在這種情況下,有可能沒有好處。有可能是一個好處的情況下,你有相對較少的「外部」的工作,但可能是許多「內部」的工作。

另一方面,它也取決於這三個工作在做什麼。如果它們本質上是異步任務(例如在數據庫中),那麼可以並行執行,但是如果它們是本地 CPU密集型任務,那麼您可能只是將額外的工作調度器沒有真正的好處。

鑑於你的代碼的樣子,這讓我感到,你可以很可能從執行單個查詢(或者也許三)和分組由yearMonth雖然受益...

4

由於外環的並行已經讓CPU保持繁忙(50k元素),並行性環路中幾乎沒有好處。爲了可讀性,我會刪除Parallel.Invoke調用來簡化代碼。

+1

假設子任務純粹是計算的。 –