使用恒定空间从磁盘流式传输数据的最有效的习惯是什么?

时间:2009-12-07 23:50:50

标签: performance streaming posix large-files mmap

问题描述

我需要从磁盘流式传输大文件。假设文件大于适合内存的文件。此外,假设我正在对数据进行一些计算,结果足够小以适应内存。作为一个假设的例子,假设我需要计算一个200GB文件的md5sum,我需要保证将使用多少ram。

总结:

  • 需要恒定的空间
  • 尽可能快
  • 假设文件非常大
  • 结果适合记忆

问题

使用常量空间从文件读取/流式传输数据的最快方法是什么?

我的想法

如果文件足够小以适应内存,那么POSIX系统上的mmap会非常快,不幸的是,这并非如此。使用缓冲区大小的mmap来缓冲文件的连续块是否有任何性能优势?系统调用将mmap缓冲区移到文件中的开销会占用任何优势吗?或者我应该使用我用fread读入的固定缓冲区吗?

3 个答案:

答案 0 :(得分:3)

我不太确定mmap会非常快(非常快的定义速度明显快于fread)。

Grep过去常常使用mmap,但切换回fread。其中一个原因是稳定性(如果文件在映射时收缩或发生IO错误,mmap会发生奇怪的事情)。这篇page讨论了一些有关这方面的历史。

您可以将系统的性能与grep选项--mmap进行比较。在我的系统上,200GB文件的性能差异可以忽略不计,但你的里程可能会有所不同!

简而言之,我将fread与固定大小的缓冲区一起使用。编码更简单,更容易处理错误,几乎肯定足够快。

答案 1 :(得分:0)

根据您使用的语言,基于您声明了特定缓冲区大小的文件的类似C的fread()循环将需要这个缓冲区大小,不多也不少。

我们通常选择4到128 kB的缓冲区大小,如果有更大的缓冲区,则几乎没有增益。

如果性能非常重要,相对较少的收益(以及重新发明某些东西的风险),可以考虑使用双线程实现,其中一个线程在一组两个缓冲区中读取文件,并且其他线程一次在一个缓冲区中执行计算顺序方式。以这种方式可以消除磁盘访问延迟。

答案 2 :(得分:0)

mjv是对的。您可以使用双缓冲区和重叠I / O.这样你的嘎吱嘎吱声和磁盘读数就可以在同一时间发生。然后,我将剖析或堆叠拍摄,以使其尽可能快。幸运的是它会比I / O更快,因此您最终会以最快的速度运行I / O而不会暂停。然后像文件碎片这样的东西出现在图片中。