如何通过玩缓冲区大小来优化读写



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

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

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

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

考虑到我使用的是非常大的二进制文件(几个10 GB),并且文件系统通常是大型读/写的最佳选择,我可以定义一个大约100 MB的缓冲区大小吗?如果会降低性能,为什么?(5)

最后,默认缓冲区是否"智能",即ifstream/ofstream将检测您正在读取/写入文件的数据量,并调整缓冲区大小以提供最大速度?(6)

您对缓冲工作方式的描述是正确的,AFAICS。

不过,大于1MB的缓冲区不太可能为您带来任何好处。事实上,最佳点可能远低于这个值。请注意,std::ifstreamstd::ofstream使用的缓冲区与磁盘缓存无关——这是内核的工作,它自行决定。流缓冲区只影响通过一个系统调用传输到内核或从内核传输的最大字节数。因此,理想的缓冲区大小并不取决于传输的数据量。依赖什么是

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

由于(1)有利于较大的缓冲器,而(2)和(3)有利于较小的缓冲器,因此在某个地方会有一个最佳点。由于CPU缓存大小可能是几兆字节左右,接近该限制的缓冲区大小将从(3)中看到严重的影响,因此最佳点肯定在1MB左右。您可能可以忽略(2),因此仍需估计(1)以获得缓冲区大小的下限。假设一个系统调用的成本大约为1000个周期,并假设CPU+内存的原始复制速度为4字节/周期。传输4k的成本大约相当于进行一次系统调用的成本。因此,当缓冲区大小为20k时,系统调用开销大约为20%,而当缓冲区尺寸为100k时,它大约为4%。因此,理想的缓冲区大小在几百kB的范围内,与文件大小无关!。

您可能会相信您的标准库实现能够做到这一点,除非评测为您提供了确凿的证据,证明存在影响性能的缓冲问题。

相关内容

  • 没有找到相关文章

最新更新