读-处理-写的最佳缓冲区大小
Posted
技术标签:
【中文标题】读-处理-写的最佳缓冲区大小【英文标题】:Optimal Buffer size for read-process-write 【发布时间】:2013-03-10 13:28:25 【问题描述】:在我的函数中,我需要将文件中的一些数据读入缓冲区,操作数据并将其写回另一个文件。该文件大小未知,可能非常大。
如果我使用一个小的缓冲区,将会有一个很长的读/写周期,并且会花费很多时间。相反,长缓冲区意味着我需要消耗更多内存。我应该使用的最佳缓冲区大小是多少?这种情况是否依赖?
我在 Windows 中看到了一些像“Tera copy”这样的应用程序,可以有效地管理大文件。还有其他我应该注意的技术或机制吗?
注意:此程序将在 Windows 下运行。
【问题讨论】:
动态缓冲区大小如何? 我说运行一些基准测试看看。也不必担心在现代 PC 上分配 1MB 或 2MB。 也许使用mmap
会有所帮助。 Linux 也有一个readahead
系统调用。
另见***.com/questions/8803515/…
【参考方案1】:
这些事情的第一条规则是进行基准测试。我的猜测是你过早地优化。如果您正在执行真正的文件 IO,则磁盘(或其他)的带宽通常会成为瓶颈。只要您将数据分成几页的块写入,性能应该不会发生太大变化。
您可能希望在写入操作的同时对部分数据进行计算。为此,您必须保留两个缓冲区,一个是当前写入的,另一个是您进行处理的。然后您将使用异步 IO 函数(在 POSIX 系统上为aio_write
,在 Windows 上可能也存在类似的东西)并为每次迭代切换缓冲区。
【讨论】:
【参考方案2】:我会建议你使用页面大小的缓冲区大小。例如页面大小为 4K,那么您可以使用 4K 字节缓冲区大小来最小化上下文切换。
【讨论】:
【参考方案3】:内存管理始终取决于大小写,尤其是与文件 I/O 结合使用时。
我有两个可能的建议。
1) 使用固定的 I/O 缓冲区大小,例如64K、256K、512KB 或 1MB。但在这种情况下,当 I/O 超过此固定缓冲区大小时,您必须考虑偏移量以在多次迭代中完成 I/O。
2) 使用 malloc() 使用可变 I/O 缓冲区大小,但这也取决于某些因素。例如系统中的可用 RAM 和操作系统中进程的最大动态内存分配限制。
【讨论】:
【参考方案4】:查看 Microsoft 对 IO 大小的看法:http://technet.microsoft.com/en-us/library/cc938632.aspx。基本上,他们说您可能应该在 64K 块中进行 IO。
在 *NIX 平台上,struct stat
有一个 st_blksize
成员,它表示应该是最小 IO 块大小。
【讨论】:
注意:这种观察到的行为和建议的根本原因是硬件原因。 TL;DR:最佳大小是您的硬件可以提供的最大尺寸,在现代“台式”计算机上似乎是 64K。【参考方案5】:虽然我不能代表算法...内存使用与处理器使用是编程中的一个典型难题,您可能应该根据具体情况进行选择...因此,如果系统有 4GB 可用 RAM,您显然可以消耗相当多,而如果你只有 512MB,你应该以使用 CPU 为代价消耗很少。最好的方法是以编程方式检查和更改您的尺寸:)
【讨论】:
这不是 CPU 与内存的问题。【参考方案6】:确实,它高度依赖于大小写,您可能应该编写程序来处理灵活的缓冲区大小,然后尝试最佳大小。
如果您从小处着手然后增加缓冲区大小,您可能会达到某个大小,之后您将看不到性能提升或性能提升非常小,因为 CPU 大部分时间都在运行您的代码,并且开销来自 I/O 的影响可以忽略不计。
【讨论】:
以上是关于读-处理-写的最佳缓冲区大小的主要内容,如果未能解决你的问题,请参考以下文章