我想了解爲什麼在以下場景中Parallel.For能夠勝過多個線程:考慮可以並行處理的一批作業。在處理這些工作時,可能會添加新工作,然後需要處理。該Parallel.For
的解決辦法如下所示:Parallel.For vs普通線程
var jobs = new List<Job> { firstJob };
int startIdx = 0, endIdx = jobs.Count;
while (startIdx < endIdx) {
Parallel.For(startIdx, endIdx, i => WorkJob(jobs[i]));
startIdx = endIdx; endIdx = jobs.Count;
}
這意味着有多次,其中的Parallel.For需要同步。考慮麪包優先圖算法算法;同步的數量會非常大。浪費時間,不是嗎?
試圖在老式的線程方法相同:
var queue = new ConcurrentQueue<Job> { firstJob };
var threads = new List<Thread>();
var waitHandle = new AutoResetEvent(false);
int numBusy = 0;
for (int i = 0; i < maxThreads; i++)
threads.Add(new Thread(new ThreadStart(delegate {
while (!queue.IsEmpty || numBusy > 0) {
if (queue.IsEmpty)
// numbusy > 0 implies more data may arrive
waitHandle.WaitOne();
Job job;
if (queue.TryDequeue(out job)) {
Interlocked.Increment(ref numBusy);
WorkJob(job); // WorkJob does a waitHandle.Set() when more work was found
Interlocked.Decrement(ref numBusy);
}
}
// others are possibly waiting for us to enable more work which won't happen
waitHandle.Set();
})));
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());
的Parallel.For
代碼當然是乾淨多了,但我無法理解,它甚至也更快!任務調度器是否很好?同步化已經結束,沒有繁忙的等待,但線程方法一直比較慢(對我來說)。這是怎麼回事?線程方法可以更快嗎?
編輯:感謝所有的答案,我希望我可以選擇多個答案。我選擇了一個也顯示出實際可能改進的那個。
如果已經有一個更清潔更快的解決方案,爲什麼要嘗試使它更快? – iMortalitySX
因爲有明顯的缺陷可以消除,我想。 –
關閉[PLinq固有的快速比System.Threading.Tasks.Parallel.ForEach](http://stackoverflow.com/questions/5196293/is-plinq-inherently-faster-than-system-threading-tasks-parallel- foreach) – iMortalitySX