File io 读取文件而不从操作系统页面缓存中退出

File io 读取文件而不从操作系统页面缓存中退出,file-io,linux-kernel,posix,File Io,Linux Kernel,Posix,(这主要用于Linux,或者理想情况下用于任何POSIX系统。) 我正在寻找一种读取大量文件(其中任何一个文件本身可能高达1GB)的方法,这些文件具有以下特点,正如我在中阅读的页面: 如果相关的磁盘页已在文件系统缓存中,则使用该页 如果相关页面不在磁盘缓存中,则会从磁盘中获取该页面,但不会逐出任何现有的缓存磁盘页面 其思想是能够读取所有这些文件,而不会污染磁盘缓存或逐出当前工作集 有什么指导吗?页面缓存大小根据系统中发生的各种进程请求的内存、I/O写回等动态变化。您可以做的是/proc/sy

(这主要用于Linux,或者理想情况下用于任何POSIX系统。)

我正在寻找一种读取大量文件(其中任何一个文件本身可能高达1GB)的方法,这些文件具有以下特点,正如我在中阅读的页面:

  • 如果相关的磁盘页已在文件系统缓存中,则使用该页
  • 如果相关页面不在磁盘缓存中,则会从磁盘中获取该页面,但不会逐出任何现有的缓存磁盘页面
其思想是能够读取所有这些文件,而不会污染磁盘缓存或逐出当前工作集


有什么指导吗?

页面缓存大小根据系统中发生的各种进程请求的内存、I/O写回等动态变化。您可以做的是/proc/sys/vm/swappiness值

在Linux上,您可以尝试使用
O\u DIRECT
open()
标志<代码>手动开启(2):


最好的方法可能是使用
posix\u fadvise()
。在读取整个文件之前,对其应用
POSIX_FADV_NOREUSE
标志似乎是最合适的;不幸的是,这个标志对当前内核没有任何作用

您可以尝试的方法是从文件中读取一块数据,然后立即告诉内核您不再需要使用
POSIX\u FADV\u DONTNEED
标记
fadvise()

使用posix_fadvise,您可以提示操作系统应该从缓存中删除某些文件块。再加上mincore提供的信息,告诉我们当前缓存了哪些块,我们可以在不干扰缓冲区缓存的情况下更改应用程序以使其工作

详细描述了[un]实现的内核功能的这一令人愉快的解决方法:

[编辑]内核预读的含义 为了获得完整的阅读性能,您应该确保只删除已经阅读的页面。否则,您将删除内核预先读取的页面:)。(我认为这应该被检测为预读错误预测,这将禁用它,至少可以避免大量浪费IO。但是预读非常有用,所以您希望避免禁用它)

此外,我打赌如果你在上次阅读之前测试页面,那么它们总是显示为核心。它不会告诉你是否有其他人在使用它们。它将显示的只是内核预读正在工作:)


链接rsync补丁中的代码应该很好(忽略“所有fds的数组”攻击)。它在第一次读取之前测试整个文件。这是合理的,因为它只需要在内核中为每个4kB文件页分配1字节。

您基本上要求无限磁盘缓存—不,不是真的。我想做的是批量复制大量文件,而不会用文件污染文件系统缓存,因为这将是一个先读后忘的操作。O_DIRECT可能是最好的选择,尽管它的浏览量相当可疑。O_DIRECT标志消除了所有缓存。这不是OP想要的。@itisravi:NOTES说它取决于文件系统:“应用程序应避免将O_DIRECT和普通I/O混合到同一文件中,尤其是同一文件中的重叠字节区域。即使文件系统在这种情况下正确处理了一致性问题,总体I/O吞吐量也可能比单独使用任一模式慢。”
   O_DIRECT (Since Linux 2.4.10)
          Try  to minimize cache effects of the I/O to and from this file.
          In general this will degrade performance, but it  is  useful  in
          special  situations,  such  as  when  applications  do their own
          caching.  File I/O is done directly to/from user space  buffers.
          The O_DIRECT flag on its own makes at an effort to transfer data
          synchronously, but does not give the guarantees  of  the  O_SYNC
          that  data and necessary metadata are transferred.  To guarantee
          synchronous I/O the O_SYNC must be used in addition to O_DIRECT.
          See NOTES below for further discussion.