当前位置: 首页 > 知识库问答 >
问题:

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

皇甫福
2023-03-14

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

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

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

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

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

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

共有1个答案

郜修雅
2023-03-14

您对缓冲工作原理的描述是正确的,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的范围内。

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

 类似资料:
  • 问题内容: 我知道Java和Perl都非常努力地在读取文件时找到一种适合所有默认缓冲区大小的大小,但是我发现他们的选择越来越过时,并且在更改默认选择时遇到问题Perl。 对于Perl,我认为默认情况下会使用8K缓冲区(类似于Java的选择),我无法使用perldoc网站搜索引擎(确实是Google)找到关于如何增加默认文件输入缓冲区大小的参考,例如, 64K。 通过上面的链接,显示8K缓冲区如何不

  • 问题内容: 根据文档,使用默认缓冲区大小,而第二个构造函数允许设置缓冲区大小。 public BufferedReader(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入流。 但是,文档没有提到默认的缓冲区大小是多少。 BufferedReader的默认缓冲区大小是多少? 问题答案: 默认缓冲区大小为8192个字符 http://developer.android.com/ref

  • 根据文档,使用默认缓冲区大小,而第二个构造函数,允许设置缓冲区大小。 公共缓冲区读取器(读取器输入) 创建使用默认大小的输入缓冲区的缓冲字符输入流。 但是,文档没有提到默认缓冲区大小。 BufferedReader的默认缓冲区大小是多少?

  • 我想在我的小libgdx游戏中使用框架缓冲区。 游戏使用了,我修改了s摄像头,使其使用50宽31高的视口。然后我将的投影矩阵设置为。这样做,我有一个分辨率独立的游戏,我可以使用我自己的“世界单位”,而不是使用像素。 但是现在,如果我创建一个,我必须给它一个大小。我必须给它摄像机视口的大小还是屏幕的大小(以像素为单位)? 而且,当我渲染的东西,我可以渲染他们在,这意味着渲染在几乎在游戏窗口的中间?

  • 问题内容: 假设我想在syscall 上的Linux文件系统上写入1 GB的数据,这种情况发生在非常 繁忙的环境中 (许多相似的I / O并发)。什么是在区间的最佳缓冲区大小,说,这样做,当 不使用打开标志,或者 使用? 请没有“自己检查”的答案-我想从“文件系统”的家伙那里得到一些答案。 问题答案: 正如评论中所讨论的那样,我认为确切的大小并不重要,假设是: 文件系统大小的一小部分(请参阅Joa

  • 问题内容: 我写了一个非常简单的函数,可以从给定的URL下载图像,调整图像大小并上传到S3(使用’gm’和’knox’),我不知道我是否在正确地将流读取到缓冲区中。(一切正常,但这是正确的方法吗?) 另外,我想了解一些有关事件循环的知识,如何知道该函数的一次调用不会泄漏任何内容,也不会将’buf’变量更改为另一个已经运行的调用(否则这种情况是不可能的,因为回调是匿名的功能?) 问题答案: 总的来说