2013-07-25 54 views
8

我最近一直在使用PLINQ來執行一些數據處理。爲什麼我的Parallel.ForAll調用最終使用單個線程?

基本上我有大約4000個時間序列(所以基本上是Dictionary<DataTime,T>的實例),我在名爲timeSeries的列表中存儲。

要執行我的操作,我簡單地做:

timeSeries.AsParallel().ForAll(x=>myOperation(x)) 

如果我看看什麼是與我不同的內核發生的事情,我注意到,第一,正在用我所有的CPU和我看到的控制檯(我輸出一些日誌)同時處理幾個時間序列。

但是,這個過程很長,大約45分鐘後,記錄清楚地表明只有一個線程正在工作。這是爲什麼?

我試圖給它一些想法,並且我意識到timeSeries包含的實例更容易從myOperation在列表的開頭和結尾處理。所以,我想知道PLINQ使用的算法是否可以將4000個實例分成4個核心,每個核心有1000個。然後,當核心完成其工作分配後,它就回到閒置狀態。這意味着其中一個核心可能面臨更重的工作量。

我的理論是正確的還是有另一種可能的解釋?

我應該在運行之前對我的列表進行洗牌,還是有一些可用於解決該問題的並行性參數?

回答

5

你的理論可能是正確的,儘管有些東西叫做「工作量化」,應該對此作出反應。我不確定爲什麼這不起作用。在外端還是少數幾個(> =幾十個)大型工作?

除了洗牌您的數據,您可以使用the overloadAsParallel()接受custom Partioner。這可以讓你更好地平衡工作。

附註:對於這種情況,我寧願Parallel.ForEach(),更多的選項和更清晰的語法。

+1

據我所知,偷工作在任務上,而不是在PLINQ中的迭代。如果任務從集合中獲取一堆物品進行處理,其他任務將無法竊取這些物品。 – svick

+1

另外,這裏可能不需要自定義分區程序,[由框架提供的](http://msdn.microsoft.com/zh-cn/library/system.collections.concurrent.partitioner.create.aspx )可能就夠了。 – svick

+0

@svick - 你可能是對的,但是會指向for循環創建一堆任務嗎?看起來很笨重。 –

相關問題