当复制时,理想的内存块大小是多少?

8

我目前使用每个内存块100兆字节来复制大文件。

人们通常使用的“好”的内存块大小是多少?

编辑

感谢所有出色的回答。

我对这些概念还很陌生,所以我会尽量理解已经提到的很多概念(例如写回缓存)。我一直在学习新的东西 :)


也许你的可执行文件比 Windows 复制程序具有更高的优先级。 - BenjaminB
1
如果您的操作系统提供“statfs”,那么您可以查看它建议的块大小(f_bsize),尽管我不知道您能相信它实际上是否“最佳”。除非您真的担心在不同平台和文件系统上会发生什么,否则请在您的机器上运行几个测试,使用从非常小到非常大的不同大小。超过停止变得更快的点之后,再使用更多的内存是没有意义的。 - Steve Jessop
还可以考虑使用本地操作,例如在Windows上使用CopyFile - MSalters
@MSalters,如果我不想学习任何东西,我会考虑这个。 - Zac Blazic
6个回答

10

典型的选择是4096字节到32KB之间的块大小。使用100MB反而会适得其反。因为你会占用缓冲区,这些缓冲区可以被用于更好地作为文件系统写回缓存。

当文件完全适合于缓存时,复制文件非常快速,WriteFile()调用是简单的内存到内存复制操作。然后缓存管理器会将其延迟写入磁盘。但是当缓存中没有足够的空间时,复制速度会急剧下降,此时WriteFile()必须等待空间腾出。现在它只能以磁盘写入速度进行操作。


7

我建议您进行基准测试,并记得包括更小的块大小。在我的测试中,我得到了相当反直觉的结果。

从硬盘读写时,所有(二的幂次方)块大小在512字节和512 kB之间的速度相同。将块大小从512 kB增加到1 MB会使复制速度降低约60%。增加块大小可以再次提高速度,但永远无法回到使用小块的速度。

当所有复制的数据都在缓存内存中时,(更快的)复制速度随着块大小的增加而提高,在达到32 kB块后趋于平稳,然后在从256 kB到512 kB块时突然下降到先前速度的一半,永远无法返回先前的速度。

在此测试之后,我将多个程序中的读/写块大小从大约1 MB降至32 kB。


有一次(几年前),我在移动设备上运行了一堆带有Flash文件系统的测试,写入速度一直增加到大约256K左右,尽管在64K之后收益非常有限。但是如果我没记错的话,我只是测试了从内存到文件的写入,而不是文件复制。我们始终无法弄清楚这些大小有什么特别之处。 - Steve Jessop

2

使用如此大的块通常没有太多好处。

假设您的操作系统非常幼稚,每个读取或写入操作都会产生硬盘寻道(实际上,您经常会发现写操作被排队,读操作被预读缓存,从而减少了在应用程序代码中使用大缓冲区的好处)。

然后,每个块都会花费您(假设)2x10毫秒进行两次寻道(一次读取和一次写入),一旦实际读取和写入的时间大大超过这个时间,增加块大小就没有太多意义。一个真正快速的硬盘可能以150MB / s的速度读取和写入,那么这10毫秒将对应于1.5MB的读/写,对于超过15MB的块大小,您将获得很少的收益。

实际上,(1)您的寻道时间可能会更短,(2)您的读写带宽可能会更高,(3)您的操作系统和驱动硬件可能会为您缓存和排队事物;您可能会看到很少或没有从块大小超过约100KB的地方获得的好处。

(您应该针对各种块大小进行基准测试,并查看您在自己的系统上获得的结果。)


0
我认为这取决于您拥有的空闲内存大小。
如果您在具有例如30Mb空闲内存的计算机上使用100M块进行复制,则复制所需的时间将比使用较小(20M)块要多得多。
如果您用于复制的缓冲区大于可用空闲内存的大小,则由于虚拟内存交换,您的复制速度将比预期慢。

我不知道你的意思是否是这样,但我会检查文件大小是否大于100兆字节,如果不是,我就使用与文件大小完全相同的块。 - Zac Blazic

0

这是相当过量的。要考虑到在读取100 MB之前,您甚至还没有开始编写数据,因此文件系统驱动程序没有机会在您读取时写入任何目标文件的任何部分。磁盘可能正在写入一些碰巧经过磁头的文件部分,同时正在读取源文件(例如,请参见elevator seek)。


0

考虑到驱动器在更换磁道时必须进行寻道操作,使用块大小为63 x 512 = 32256是否能够产生最佳结果?


1
物理磁盘和程序之间存在几个操作系统和硬件层,因此磁道大小可能并不重要。不过,欢迎来到SO :-)。 - thiton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接