【问题标题】:Read file without disk caching in Linux在 Linux 中读取没有磁盘缓存的文件
【发布时间】:2013-02-22 08:26:34
【问题描述】:

我有一个只每周运行一次的 C 程序,并且只读取一次大量文件。由于 Linux 还会缓存所有读取的内容,因此它们会不必要地填满缓存,这会大大降低系统速度,除非它有 SSD 驱动器。

那么如何在不填满磁盘缓存的情况下打开和读取文件呢?

注意:

磁盘缓存是指当您读取文件两次时,第二次是从 RAM 中读取,而不是从磁盘中读取。 IE。从磁盘读取一次的数据会留在 RAM 中,因此后续读取同一文件将不需要重新从磁盘读取数据。

【问题讨论】:

  • 你会认为 Linux 会有一些关于磁盘缓存的配置。无论哪种方式,这真的是一个 C 问题吗?无论使用哪种编程语言,您都会遇到同样的问题,不是吗?您是否尝试过在 valgrind 中运行该程序?可能是你有内存泄漏。
  • 确实如此,否则可能有人发布了 python 代码示例 :)
  • 好吧,如果你没有要求 C,你会得到更多“Linux”的答案。请回答我所有的问题:您是否尝试过在 valgrind 中运行您的程序?
  • 好的,我把C标签去掉了。

标签: linux io


【解决方案1】:

您可以使用posix_fadvise()POSIX_FADV_DONTNEED 建议来请求系统释放您已阅读的页面。

【讨论】:

  • 谢谢。 POSIX_FADV_NOREUSE 不是更合适吗?刚刚看了链接。
  • 它可能会,但文档表明它是无操作的。
  • 我更喜欢使用 fadvise 而不是 O_DIRECT。您甚至可以让另一个程序定期告诉系统它不需要缓存某些文件。我在使用 awstats 解析大型日志文件时就是这样。
  • 您可以使用 POSIX_FADV_NOREUSE before 读取数据和 POSIX_FADV_DONTNEED after 读取数据。 POSIX_FADV_NOREUSE 目前是无操作的,但也许有一天会实现。
  • 正如github.com/jborg/attic/issues/252 中所建议的,Linux 中的当前实现将无条件清除缓存页面,可能会降低使用相同文件的其他应用程序的性能。
【解决方案2】:

我相信将O_DIRECT 传递给open() 应该会有所帮助:

O_DIRECT(自 Linux 2.4.10 起)

尽量减少此文件的 I/O 对缓存的影响。一般来说,这会降低性能,但在特殊情况下很有用,例如当应用程序进行自己的缓存时。文件 I/O 直接与用户空间缓冲区进行。 O_DIRECT 标志自己努力同步传输数据,但不保证 O_SYNC 传输数据和必要的元数据。为了保证同步 I/O,除了 O_DIRECT 之外,还必须使用 O_SYNC。

O_DIRECTman page 底部有更详细的注释,包括来自 Linus 的有趣引述。

【讨论】:

  • 只是为了确定,因为它说“通常这会降低性能” - 它实际上不会降低它对我的影响,对吧?因为我真的只读过一次文件。
  • @sashoalm:我认为这正是它的意思。它会降低重复读取的性能。但是,由于您没有重复阅读,因此这不适用于您。如果有的话,它应该可以提高你的性能,因为你不会不必要地污染缓存。
  • IIRC,这将禁用预读,这可能是性能下降的原因
  • 确实如此。如果您要逐个字符地读取字符,则没有缓存意味着,那么驱动器将为每个字符搜索一次,而不是为 4KB 搜索一次,这是搜索的 4096 倍。我认为这不是 OP 想要的。
  • @modifiablelvalue:这不完全正确:您甚至无法使用O_DIRECT 读取一个字符。这在我链接到的手册页中有详细介绍。仅引用一句话:在 Linux 2.4 下,传输大小以及用户缓冲区和文件偏移的对齐方式都必须是文件系统逻辑块大小的倍数。在 Linux 2.6 下,对齐到 512 字节边界就足够了。
猜你喜欢
  • 1970-01-01
  • 2011-12-18
  • 2017-01-27
  • 2010-11-03
  • 1970-01-01
  • 2014-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多