C# 是并行文件。读取速度比顺序读取快吗?

C# 是并行文件。读取速度比顺序读取快吗?,c#,file-io,C#,File Io,我只是想知道是并行文件。使用PLINQ/parallel读取会更快吗?我的代码如下(.Net 4.0): publicstaticvoidreadfileparallel(列表文件名) { Parallel.Foreach(文件名,file=>file.Read(file)); } 公共静态void ReadFilePLINQ(列表文件名) { fileName.aspallel().foreach(file=>file.Read(file)); } 我问这个问题的原因是因为我认为文件读取是I

我只是想知道是并行
文件。使用PLINQ/parallel读取
会更快吗?我的代码如下(.Net 4.0):

publicstaticvoidreadfileparallel(列表文件名)
{
Parallel.Foreach(文件名,file=>file.Read(file));
}
公共静态void ReadFilePLINQ(列表文件名)
{
fileName.aspallel().foreach(file=>file.Read(file));
}

我问这个问题的原因是因为我认为文件读取是IO绑定的,所以并行处理不会有帮助,对吗?

MSFT有一个非常好的PDF,它详细介绍了并行和线程的可能性

这可能会有帮助

这要看情况而定

如果您的文件位于不同的位置、不同的网络共享或不同的物理硬盘驱动器上,那么并行加载可能会有所帮助。如果它们位于一个旋转的硬盘驱动器上,并行读取文件可能会大大降低性能,因为这些并行读取可能会导致额外的寻道时间


如果您的文件位于SSD上,您可能会获得稍低的性能,但这取决于并行读取的文件数量及其大小。我认为,在一定的文件大小阈值和并行读取次数下,性能将显著下降。如果没有一些实验,很难说出来

你会这么认为,但测量结果并不是这样的。当文件I/O有很大的延迟时,特别是在网络上,并行执行可以保持管道充满。

第一种近似情况是,如果文件位于不同的磁盘上,则会有所帮助,否则会使速度变慢(因为搜索时间增加)

如果缓存所有文件,速度可能会稍快一些(因为可以使用多个核心)


当然,你最好的选择是运行一些基准测试。

你并不是在做一个并行文件。读取,你是在做多个文件。并行读取。如果文件位于不同的磁盘轴中,您只需一次使用多个磁盘轴就可以提高吞吐量


即使使用单个主轴,如果每次读取后都执行CPU限制的处理,也可以体验到性能的提高,尽管在这种情况下,任务和调度对象会更好。在这种情况下,您可以让一些任务从文件加载数据,而另一些任务则使用已加载的数据执行一些繁重的处理。

我认为您在这方面已经做得非常到位了

一般来说,并行操作总是受到资源耗尽的限制,无法在该点上并行运行操作,但即使如此,在数量不断增加的并行线程上,仍然会有递减的回报

杰夫·阿特伍德(Jeff Atwood)在推特上发布了一个有趣的图表,我将在后面添加该图表,显示多线程环境下多核处理器的收益递减。当然,这并不完全相同。但是,让我们从这样一个角度来看待这个问题:即使在100个硬盘上有100个文件,IO也会在某个地方被压回一个通道,这会导致读取量的增加有所减少


我基本上想说的是,并行运行并不意味着它会急剧增加,重要的是要考虑并行进程实际上是如何被执行的。

< P>这是一个棘手的事务。如果操作错误,磁头会来回移动,试图同时读取两个文件。对于较大的文件,这尤其是一个问题

但是,如果您并行读取大量小文件,您可能会获得一些好处,因为磁盘子系统可以选择以不同于您要求的顺序读取文件。然而,我在现实生活中没有看到这种效果


您对内容所做的处理也可以与读取文件并行进行。因此,在发布之前,您需要进行概要分析和基准测试

这些都是合理的标准。在实践中,我会说测量它而不是猜测。是的,但是如果他的文件在同一个硬盘上,他将达到头部搜索时间,吞吐量将下降2倍。请记住,3.5英寸7200 RPM驱动器的平均寻道时间为13-15毫秒。与容量和线性读/写速率不同,这一数字在过去几年中是一致的。这就是为什么我说“每次读取后都会执行CPU限制的处理”。当一个线程读取文件时,另一个线程正在处理,因此这两个线程都能正常工作。
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));
}