2013-03-21 90 views
13

在我的函数中,我需要从文件读取一些数据到缓冲区,操作数据并将其写回到另一个文件。该文件的大小未知,可能非常大。用于读取进程写入的最佳缓冲区大小

如果我使用一个小缓冲区,会有一个很长的读/写周期,这将需要很长时间。相反,长缓冲区意味着我需要消耗更多的内存。什么是我应该使用的最佳缓冲区大小?这个案件是否依赖?

我在窗口中看到了一些类似'Tera copy'的应用程序,可以有效地管理大型文件。有什么其他技术或机制我应该知道吗?

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

+1

动态缓冲区大小如何? – Mysticial 2013-03-21 06:20:18

+2

我说运行一些基准来看看。另外,不要担心在现代PC上分配1MB或2。 – drescherjm 2013-03-21 06:20:22

+1

也许使用'mmap'可能会有所帮助。 Linux也有一个'readahead'系统调用。 – 2013-03-21 06:21:43

回答

15

看看微软有关IO尺寸:http://technet.microsoft.com/en-us/library/cc938632.aspx。基本上,他们说你应该在64K块中做IO。

在* NIX平台上,struct stat有一个st_blksize成员,它说什么应该是最小的IO块大小。

+1

注意:这种观察行为和建议的根本原因是硬件问题。 TL; DR:*最佳*大小是您硬件可以提供的最大数量,在现代“桌面”计算机上似乎为64K。 – 2013-03-21 09:32:36

6

事实上,这的确与案例有很大关系,您应该编写自己的程序,以便能够处理灵活的缓冲区大小,然后尝试优化哪些大小。

如果从小尺寸开始,然后增加缓冲区大小,您可能会达到一定的大小,之后您将看不到或性能增益极小,因为CPU花费大部分时间运行代码,并且来自I/O的开销变得微不足道。

-1

虽然我不能说出算法...内存使用与处理器使用是编程中的典型困境,您应该根据具体情况选择...因此,如果系统具有4GB可用RAM,您可以明显消耗相当多,而如果你只有512MB,那么你就应该花费很少的代价来执行CPU。最好的方法是在语法上检查和改变你的尺寸:)

+2

这不是CPU与内存问题。 – 2013-03-21 06:30:46

1

内存管理始终与个案有关,尤其是与文件I/O结合使用时。

我有两种可能的建议。

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

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

0

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

1

这些事情的首要规则是基准。我的猜测是你过早地优化。如果你正在做真正的文件IO,你的磁盘带宽(或其他)通常会成为瓶颈。只要你将数据写入几页的数据块,性能不应该改变太多。

你可能希望做的是对你的写操作并行计算部分数据。为此,您将不得不保留两个缓冲区,一个是当前写入的缓冲区,另一个是您处理的缓冲区。然后你可以使用异步IO功能(POSIX系统上的aio_write,也可能类似于Windows的),并为每次迭代切换缓冲区。

相关问题