2010-07-13 37 views
6

我只是想知道使用PLINQ/Parallel可以更快地平行File.Read嗎?我的代碼如下所示(.NET 4.0):是並行File.Read快於順序讀取?

public static void ReadFileParallel(List<string> fileName) 
{ 
    Parallel.Foreach(fileName, file=>File.Read(file)); 
} 

public static void ReadFilePLINQ(List<string> fileName) 
{ 
    fileName.AsParallel().foreach(file=>File.Read(file)); 
} 

我問這個是因爲我認爲這個文件讀取IO束縛的原因,這樣做平行不會幫助,是嗎?

回答

6

這取決於。

如果您的文件位於不同的位置,不同的網絡共享或不同的物理硬盤上,那麼是的,並行加載可能會有所幫助。如果他們使用單個旋轉硬盤驅動器,並行讀取文件可能會嚴重影響您的性能,因爲您可能會因這些並行讀取而導致額外的搜索時間。

如果您的文件位於SSD上,您的性能可能會稍差,但這取決於您並行讀取的文件數量以及它們的大小。我想象一下,在一定的文件大小閾值和並行讀取次數下,性能會顯着下降。很難告訴那個沒有實驗的人。

+1

這些都是合理的標準。但在實踐中,我會說測量它而不是猜測。 – 2010-07-13 14:09:24

1

你會這樣想,但那不是測量結果顯示的。當文件I/O具有嚴重延遲時(尤其是通過網絡)時,並行處理可以保持管道充滿。

0

如果文件位於不同的磁盤上並且使其速度變慢(由於花費更多時間尋找),第一個近似值將有所幫助。

如果所有文件都被緩存(因爲您可以使用多個核心),速度可能會稍快。

你最好的選擇是運行一些基準測試。

0

你並不是正在做一個並行的File.Read,你正在並行地執行多個File.Reads。如果這些文件位於不同的主軸上,只需一次使用多個主軸,就可以提高吞吐量。

即使您使用單個主軸,如果每個Read之後都有CPU綁定處理,您也可以體驗到改進的性能,但在這種情況下,對任務對象進行調度會更好。在這種情況下,您可以有一些任務從文件加載數據,而另一些則使用已加載的數據來執行一些繁重的處理。

+0

是的,但是如果他的文件在同一個硬盤上,他就會打到頭部搜索時間,吞吐量會下降2倍。 請記住,3.5英寸7200 RPM驅動器的平均尋道時間爲13-15毫秒,與容量和線性讀寫速率不同,這個數字在過去幾年中是一致的 – Soonts 2010-07-13 14:23:47

+0

這就是爲什麼我說「每次讀取之後CPU綁定處理「,當一個線程正在讀取文件時,另一個線程正在處理中,因此兩個線程都處於工作狀態。 – 2010-07-13 17:36:02

0

我認爲你已經在這裏碰到了頭。

並行操作一般總是受限於資源用盡並行運行操作的點,但即使如此,在並行線程數量不斷增加的情況下,您仍然會減少回報。

Jeff Atwood在推特上發佈了一張有趣的圖表,我將在後面添加一個有趣的圖表,展示多線程環境下多核處理器的收益遞減。當然,這不完全相同。但是讓我們從這個想法來看待這個問題,即使100個硬盤驅動器上有100個文件,IO的某個地方也會降低到單個通道,這會導致讀取增加量減少。

我基本上試圖說的僅僅是並行運行並不意味着它會大幅加速,重要的是要考慮並行進程是如何實際執行的。

0

這是棘手的業務。如果你做錯了,磁盤頭會來回移動,試圖同時讀取兩個文件。這尤其是對大文件的一個問題。

但是,如果您並行讀取大量小文件,則可能會稍微增加一點,因爲磁盤子系統可以選擇以不同於您詢問的順序讀取文件。但是,在現實生活中我沒有看到這種效果。

同時處理你對內容的處理可以與讀取文件並行完成。因此,您需要在發貨之前進行配置和基準測試。