读-处理-写的最佳缓冲区大小

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 的影响可以忽略不计。

【讨论】:

以上是关于读-处理-写的最佳缓冲区大小的主要内容,如果未能解决你的问题,请参考以下文章

如何定义通道缓冲区的最佳大小? [关闭]

单片机环形对接溢出如何处理

write(2)最佳的缓冲大小

在 OpenGL 中处理 FBO 的最佳方法是啥?

GetUserNameEx() 返回的缓冲区大小

Proactor模型