如果并行执行磁盘文件操作会更快吗?

Posted

技术标签:

【中文标题】如果并行执行磁盘文件操作会更快吗?【英文标题】:Are disk file operations faster if executed in parallel? 【发布时间】:2015-10-04 09:10:39 【问题描述】:

考虑有 N 个文件要完全写入磁盘(即从所有文件缓冲区中刷新)。对于每个文件,我们写入少量(相对于 HDD 寻道时间)的数据,例如64KB,带有WriteFile,然后对该文件调用FlushFileBuffers,以确保该文件的数据完全刷新到硬盘。

如果我们按顺序逐个写入和刷新文件,那么我预计大约需要时间N*seekTime + N*writeTime,其中seekTime 是将硬盘驱动器磁头定位到正确扇区的时间(可能需要直到全盘旋转的时间),writeTime 是磁盘顺序写入 64KB 数据所需的时间。通过这种一对一的方法,我们没有给操作系统优化空间,因为我们定义了文件必须刷新的顺序。

在操作系统的一些支持下,可以通过重新排列文件写入和刷新的顺序来实现性能改进,以便考虑磁盘旋转(即磁头在磁盘上的当前位置)重新排列文件操作,以便从那些开始几乎不需要旋转(即最接近磁盘磁头当前位置)并以需要几乎完全旋转磁盘的那些结束。

问题是:操作系统(尤其是 Windows)是否提供这种优化?换句话说,是否可以通过在 N 个线程中并行运行文件写入和刷新操作来提高性能,每个文件一个线程?还是会导致额外的重新定位操作降低性能(作为硬盘的一种上下文切换)?

【问题讨论】:

对桡骨头运动进行了优化。操作系统不知道轴向位置。 【参考方案1】:

您应该首先问自己,并在此处解释为什么需要冲洗。您想要实现的不一定是实际发生的。

如果您确实想以某种方式优化应用程序,从而在物理设备上产生某种访问模式,那么您的解决方案就非常依赖于硬件。对您的测试用例进行的优化可能会在另一种情况下达到相反的效果。例如,文件碎片怎么办? RAID磁盘呢?网络文件系统呢? SSD驱动器呢?同一台机器上运行的其他进程并发访问同一个磁盘会怎样?

使磁盘访问快速的关键是缓冲。如果你不是绝对需要打败它,就不要打败它。

【讨论】:

出于持久性的目的,我需要刷新:以确保在执行下一步之前将数据实际写入磁盘。我可以按任何顺序甚至并行刷新这 N 个文件。重要的是达到将每个文件的数据物理写入磁盘的程度。让我们将范围限制在旋转磁盘(无 SSD),忽略文件碎片(假设用户定期对磁盘进行碎片整理以提高性能),没有网络文件系统,忽略其他进程的磁盘访问。 RAID 很有趣。我们不要采取“不要优化任何东西,因为它没有意义”的方法。 当发现有必要进行优化时,我并不想阻止它。我只是想确保你意识到你想要的可能会导致一个脆弱的解决方案,它可能会在任何时候停止产生你想要的好处,并且出于多种原因。如果你意识到这一点,很好。 我知道并发症。这就是我在 *** 上提出问题的原因之一,而不是仅仅对这两个选项进行基准测试并在我的机器和测试用例中选择更快的那个。我提出这个问题是为了从根本上理解问题,以便(在某种程度上)预测所选解决方案在我的性能测试用例未涵盖的情况下将如何工作。关键问题是操作系统(尤其是 Windows)是否(以及如何)优化了针对不同文件并行出现的 HDD 写入+刷新请求。【参考方案2】:

您需要进行基准测试,因为它是操作系统、文件系统和硬件特定的。在我的 Linux 系统上,许多文件操作都是通过page cache 进行的,所以如果两个程序(或同一个程序运行两次)几乎同时访问一个文件,最新的访问可能不涉及任何物理磁盘 I/O。 Linux 和 POSIX 甚至有一些系统调用来帮助页面缓存(posix_fadvise(2)、madvise(2)、readahead(2)...)

我不了解 Windows,但听说并相信在这种缓存方面它比 Linux 效率低的谣言。

硬件限制通常是一个非常重要的瓶颈。用 SSD 替换磁盘可能是值得的。

AFAIK、旧的 BSD、SunOS 和 Linux 磁盘驱动程序进行了您建议的优化(重新组织 I/O 操作以降低查找和旋转延迟)。今天,这并不重要(磁盘控制器本身会将“逻辑”扇区映射到“物理”扇区)。

【讨论】:

【参考方案3】:

我相信 Windows 不会进行任何 IO 调度,实际上它甚至会将大型 IO 分成 256KB 的片段。 Linux 内置了 IO 调度。

也就是说,一些驱动程序和磁盘会进行一些重新排序。通常,IO/sec 速率会增加到队列深度更高的点。 Crystal Disk benchmark 有一个 QD32 模式。

SSD当然做的事情很容易从具有高队列深度的基准中看到。 SSD 还具有硬件并行性。当您增加随机读取的队列深度时,它们会变得更快。

我在 Windows 上的桌面磁盘上发现,顺序小直写 IO 的发生速度比磁盘寻道速度快得多。要么控制器是写缓存,要么磁盘几何结构确实适合顺序写入,即使没有缓存。

【讨论】:

以上是关于如果并行执行磁盘文件操作会更快吗?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Task 执行长耗时的任务时,会堆集并行执行吗?

Spring Task 执行长耗时的任务时,会堆积并行执行吗?

为啥并行多线程代码执行比顺序慢?

并行流在不同的操作下可以正常工作吗?

jQuery的$.ajax方法支持同时创建多个异步ajax请求吗?而且这些ajax对象必须是并行处理的

当我执行多个优于 Runtime.getRuntime().availableProcessors()) 的并行线程时,为啥我的 Java 程序运行得更快?