如何通过播放缓冲区大小来优化读写?

Vin*_*ent 4 c++ buffer file stream c++11

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

我不确切知道缓冲区的作用,所以你可以确认:

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

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

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

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

fgp*_*fgp 7

您对缓冲如何工作的描述是正确的,AFAICS.

但是,大于1 MB的缓冲区不太可能为您带来任何好处.实际上,最佳点可能远低于该值.需要注意的是所用的缓冲区通过std::ifstreamstd::ofstream无关与磁盘高速缓存-这是内核的工作,它在它自己的判断.流缓冲区仅影响使用一个系统调用传输到内核或从内核传输的最大字节数.因此,理想的缓冲区大小取决于您传输的数据量.什么是依赖于为

  1. 系统调用的开销成本.更高的开销意味着您需要一次性传输更多数据.
  2. 缓冲管理的开销成本.对于较大的缓冲区,可能更大,如果有的话.
  3. CPU缓存垃圾影响.将强烈支持较小的缓冲区.

因为(1)有利于更大的缓冲区,而(2)和(3)有利于更小的缓冲区,所以某处会有一个甜点.由于CPU缓存大小可能是几兆字节左右,接近该限制的缓冲区大小将从(3)看到严重影响,因此最佳位置肯定低于1 MB左右.您可以忽略(2),因此仍需要估计(1)以获得缓冲区大小的下限.假设系统调用大约花费大约1000个周期左右,并假设CPU +内存的原始复制速度是4个字节/周期.转移4k然后花费与做一个系统调用一样多.因此,缓冲区大小为20k,系统调用开销大​​约为20%,缓冲区大小为100k时,大约为4%.因此,理想的缓冲区大小在几百KB的范围内,与文件大小无关!

你也许可以相信你的标准库的实现来获得这种权利,除非分析提供了确凿的证据,有一个缓冲问题,它会影响性能.