任何人都可以/應該使用.NET 4.0中引入的類別Partitioner
的典型場景嗎?何時使用分區類?
何時使用分區類?
回答
的Partitioner
類是用來做並行執行更多的矮胖。如果你有很多非常小的任務並行運行,那麼爲每個任務調用委託的開銷可能會很高。通過使用Partitioner
,可以將工作負載重新排列爲塊,並且每個並行調用都可以在稍大的集合上工作。這個類抽象出這個特性,並且能夠根據數據集和可用內核的實際情況進行分區。
示例:假設您想要像這樣並行運行一個簡單的計算。
Parallel.ForEach(Input, (value, loopState, index) => { Result[index] = value*Math.PI; });
這將調用Input中每個條目的委託。這樣做會增加每個開銷。通過使用Partitioner
,我們可以做這樣的事情
Parallel.ForEach(Partitioner.Create(0, Input.Length), range => {
for (var index = range.Item1; index < range.Item2; index++) {
Result[index] = Input[index]*Math.PI;
}
});
這將減少所調用的數量,因爲每個調用將在更大的一組工作。根據我的經驗,這可以在非常簡單的操作並行化時顯着提升性能。
要並行化數據源上的操作,其中一個基本步驟是將源分區爲可由多個線程同時訪問的多個部分。當您編寫並行查詢或ForEach循環時,PLINQ和任務並行庫(TPL)提供默認分區程序,這些分區程序可以透明地工作。對於更高級的場景,你可以插入你自己的分區器。
更多here:
我添加到:一般來說*你*不使用它。 PLINQ的確如此,你可能會逃脫默認分區。 – 2010-10-27 09:51:24
如Brian Rasmussen所建議的,範圍分區是一種在CPU密集型工作時應該使用的分區類型,往往很小(相對於虛擬方法調用),必須處理許多元素,並且當涉及到每個元素的運行時間時,大多是不變的。
應該考慮的另一種類型的分區是塊分區。這種類型的分區也被稱爲負載平衡算法,因爲工作線程在很多工作要做的時候很少會閒置 - 這不是範圍分區的情況。
當工作有一些等待狀態時,應該使用塊分區,每個元素往往需要更多的處理,或者每個元素可能有明顯不同的工作處理時間。
這樣做的一個例子可能是讀入內存並處理大小不同的100個文件。 1K文件的處理時間比1mb文件少得多。如果爲此使用範圍分區,則某些線程可能會閒置一段時間,因爲它們碰巧處理較小的文件。
與範圍分區不同,無法指定每個任務要處理的元素數 - 除非您編寫自己的定製分區程序。使用塊分區的另一個缺點是,當它返回到另一個塊時可能會有一些爭用,因爲在此時使用了排它鎖。所以,很顯然,一個塊分區不應該用於短時間的CPU密集型工作。
默認塊分區程序以每個塊的塊大小爲1個元素開始。在每個線程處理三個1元素塊之後,塊大小每塊增加到2個元素。每個線程處理了三個2元素塊後,塊大小再次遞增爲每個塊3個元素,依此類推。至少這是按照 Dixin Yan(參見塊分區部分)爲Microsoft工作的方式。
順便說一下,他博客中的可視化工具好像是Concurrency Visualizer profile tool。 docs for this tool聲稱它可用於定位性能瓶頸,CPU利用率低下,線程爭用,跨核心線程遷移,同步延遲,DirectX活動,重疊I/O區域以及其他信息。它提供了圖形,表格和文本數據視圖,可以顯示應用程序中的線程與整個系統之間的關係。
其他資源:
- 1. 使用#define來區分調用類
- 2. 區分使用SFINAE和void_t的類型
- 3. 使用分區
- 4. 如何區分類? ios7
- 5. 如何區分何時調用viewDidAppear
- 6. 如何在Oracle中使用交換分區進行分區和子分區?
- 7. MVC3何時使用區域?
- 8. MySQL - 使用密鑰分區時將數據分佈不均勻分區
- 9. 如何使用Hive HQL創建分區表'像'未分區表?
- 10. TimeZone - 如何區分GMT時區和無法識別的時區?
- 11. 即時分區
- 12. 區分兩個類
- 13. 如何使用包名來區分grails中的類?
- 14. 用於GPT分區表的啓動分區類型
- 15. 使用瑟茜爲普通類(不區分類別)
- 16. 使用scikit-learn來區分類似的類別
- 17. 使用joda API和UTC時區錯誤時差(分鐘/小時)
- 18. 按小時分組並按軌道使用用戶時區?
- 19. 如何在使用scanf時區分整數和字符()
- 20. 如何區分使用GitExtensions時的當前文件
- 21. 如何在使用pinMode時區分模擬和數字引腳?
- 22. Highcharts如何使用時間百分比區域
- 23. 如何使用搜索欄區分基於時間的數據?
- 24. 如何區分使用execvp時的執行情況?
- 25. 如何區分使用運算符時的讀/寫操作[]
- 26. 如何在使用scanf和'%d'時區分int和char
- 27. 使用MediaMetadataRetriever時如何區分文件無效?
- 28. 如何在使用MVC時刷新特定分區
- 29. 如何在使用顯示時顯示分區:無
- 30. 如何使用angularjs區分HTML選項?
Partitioner.Create()的默認rangeSize是1。因此,這兩個代碼示例的分區是相同的。除非Partitioner.Create(0,Input.Length,i);其中i> 1,它仍然具有相同數量的線程。 – Pingpong 2014-01-24 15:31:28