提问者:小点点

如何玩转缓冲区大小优化读写?


如何在标准C++/C++11(无POSIX函数)中优化std::ifstream和std::ofstream的读写速度?(1<-由于有几个问题,这些数字标识了不同点)

我不知道缓冲区的确切作用,所以你能确认一下吗:

  • 用于读取:文件的大部分预加载在内存中(因此缓冲区大小定义了这大部分的大小)(2)
  • 写入:数据写入内存,一旦缓冲区满了,数据就从内存传输到文件系统(3)

如何设置std::ifstream和std::ofstream上的缓冲区大小?(4)

考虑到我使用的是非常大的二进制文件(几个10 GB),而且文件系统通常最适合进行大的读/写操作,我可以定义一个类似100 MB的缓冲区大小吗?如果它会降低性能,为什么?(5)

最后,缺省缓冲区是否“聪明”,即IFStream/OfStream将检测您正在读取/写入文件的数据量,并调整缓冲区大小以提供最大速度?(六)


共1个答案

匿名用户

您对缓冲工作原理的描述是正确的,FAICS。

但是,大于1 MB的缓冲区不大可能为您买到任何东西。实际上,甜点可能远低于这个值。请注意,std::ifstreamstd::ofstream使用的缓冲区与磁盘缓存无关-这是内核的工作,它可以自行决定。流缓冲区只影响通过一个系统调用向内核传输或从内核传输的最大字节数。因此,理想的缓冲区大小并不取决于您传输了多少数据。is所依赖的是is

  1. 系统调用的开销。较高的开销意味着您希望一次性传输更多的数据。
  2. 缓冲区管理的开销。如果有更大的缓冲区,可能会更大。
  3. CPU缓存丢弃效果。将大力支持较小的缓冲区。

由于(1)有利于较大的缓冲区,而(2)和(3)有利于较小的缓冲区,所以在某处会有一个最佳位置。由于CPU缓存大小可能是几兆左右,接近该限制的缓冲区大小将看到(3)的严重影响,因此最佳位置肯定在1兆左右。您可能可以忽略(2),因此仍然需要估计(1)以获得缓冲区大小的下限。假设一个syscall花费大约1000个周期,并且假设CPU+内存的原始复制速度是4字节/周期。那么,传输4K的成本与执行一个系统调用的成本差不多。因此,当缓冲区大小为20K时,syscall开销大约为20%,而当缓冲区大小为100K时,大约为4%。因此,理想的缓冲区大小与文件大小无关,在几百kB的范围内。

您可能可以相信您的标准库实现能够正确地完成这一任务,除非分析为您提供了影响性能的缓冲问题的确凿证据。