2011-12-05 68 views
2

當你產生多個任務,比如:並行編程TPL

for (int i = 0; i < 1000000; i++) { 
     // create a new task 
     tasks[i] = new Task<int>((stateObject) => { 
      tls.Value = (int)stateObject; 

       for (int j = 0; j < 1000; j++) { 
       // update the TLS balance 
       tls.Value++; 
       } 

      return tls.Value; 
      }, account.Balance); 

     tasks[i].Start(); 
} 

這些工作基本上都是在ProcessThread運行。因此,我們可以爲1,000,000個任務分割1個進程線程1,000,000次。

是否是TPL任務調度程序查看操作系統並確定在多核機器中有8個虛擬進程線程,然後在這8個虛擬進程線程中分配1,000,000個任務的負載?

+0

我不確定語法,但邏輯似乎是正確的。我會推薦parallel.for – Bengie

回答

6

Nows的任務基本上在ProcessThread上運行..因此,我們可以爲1000000個任務切片1個進程線程1000000次。

這是不正確的。一個任務!=一個線程,特別是不等於一個ProcessThread。多個任務將被安排到單個線程上。

難道是TPL任務schduler,着眼於操作系統和判斷,我們有8級虛擬進程的線程在多核機器,等於是在這些8個vgirtual進程線程分配100萬級的任務負載?

實際上,是的。當使用默認的TaskScheduler(你在上面做的)時,任務在ThreadPool線程上運行。 1000000個任務不會創建1000000個線程(儘管它會使用超過8個字節的提示...)

這就是說,數據並行性(例如在巨型for循環中循環)通常要好得多通過Parallel.ForParallel.ForEach。 Parallel類將在內部使用Partitioner<T>將工作分解爲更少的任務,這將爲您提供更好的整體性能,因爲它將具有更少的開銷。欲瞭解更多詳情,請登錄Partitioning in the TPL

1

粗略地說,您當前的代碼在ThreadPool上推送1000000個任務。當任務需要一些重要時間時,您可能會遇到問題。

在這樣的情況下,一定要使用

Parallel.For(0, 1000000, ...); 

,然後你不僅有調度,但更重要的還一個分區幫助你分配負載。
更不用說它更可讀。