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

17

在我的函数中,我需要从文件中读取一些数据到缓冲区中,对数据进行处理并将其写回另一个文件。该文件的大小未知,可能非常大。

如果我使用小缓冲区,读/写循环会很长,花费很多时间。相反,长缓冲区意味着我需要消耗更多的内存。我应该使用什么样的最佳缓冲区大小?这种情况是否依赖于特定情况?

我看到 Windows 上的 'Tera copy' 等应用程序可以高效地管理大型文件。是否还有其他技术或机制我应该了解?

注意:此程序将在 Windows 下运行。


1
动态缓冲区大小怎么样? - Mysticial
2
我建议运行一些基准测试来查看。同时,不用担心在现代电脑上分配1MB或2MB的内存。 - drescherjm
2
也许使用 mmap 可以帮助解决问题。而且 Linux 也有一个 readahead 系统调用。 - Basile Starynkevitch
请参见https://dev59.com/zF_Va4cB1Zd3GeqPQB3B。 - Raedwald
6个回答

25

1
注意:观察到这种行为的根本原因和建议是硬件问题。简而言之:最佳大小是您的硬件可以提供的最大值,在现代“桌面”计算机上似乎为64K。 - Matthieu M.

6

实际上,这与具体情况高度相关,你应该编写程序以处理灵活的缓冲区大小,然后尝试找到最佳大小。

如果您从小开始,然后增加缓冲区大小,那么很可能会达到某个大小,此后您将看不到或几乎没有性能提升,因为CPU大部分时间都在运行您的代码,而I/O的开销已经变得微不足道。


2
这些事情的第一条规则是基准测试。我猜你过早地进行了优化。如果你正在进行真正的文件IO操作,你的磁盘(或其他设备)的带宽通常会成为瓶颈。只要你将数据以多个页面的块写入,性能就不应该发生太大变化。
你可以希望在写操作并行处理数据的某些部分时进行计算。为此,您需要保留两个缓冲区,一个正在写入,另一个用于处理。然后,您将使用异步IO函数(在POSIX系统上为aio_write,在Windows上可能也存在类似功能),并在每次迭代时切换缓冲区。

1

内存管理通常是与文件I/O结合使用的,具体情况具体分析。

我有两个建议:

1)使用固定的I/O缓冲区大小,例如64K、256K、512KB或1MB。但在这种情况下,当I/O超过此固定缓冲区大小时,您必须考虑偏移量以完成多次迭代的I/O。

2)使用可变的I/O缓冲区大小,使用malloc()函数,但这也取决于某些因素,例如系统中可用的RAM和进程的最大动态内存分配限制。


0
我建议您使用页面大小的缓冲区大小。例如,如果页面大小为4K,则可以使用4K字节的缓冲区大小来最小化上下文切换。

-2

虽然我不能代表算法发言...内存使用与处理器使用是编程中的经典困境,你应该根据具体情况进行选择...所以如果系统有4GB可用RAM,你显然可以消耗相当多的内存,而如果只有512MB,你应该尽量少消耗内存,以换取CPU的使用。最好的方法是通过编程方式检查和更改你的大小 :)


4
这不是CPU和内存之间的问题。 - Emil Vikström

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