Linux中的无缓冲I/O.

stu*_*uck 9 linux filesystems file-io fopen

我写很多很多,不会被几个星期再次读取数据 - 我的程序运行的可用内存的机器上量(与"自由"或"顶"显示)下降速度非常快,内存量我应用程序使用不会增加 - 其他进程使用的内存量也不会增加.

这让我相信文件系统缓存正在消耗内存 - 因为我不打算长时间读取这些数据我希望绕过系统缓冲区,这样我的数据就会直接写入磁盘.我没有改善性能或成为超级忍者的梦想,我的希望是给文件系统一个提示,我不会很快回来为这个记忆,所以不要花时间优化这些情况.

在Windows上,我遇到了类似的问题,并使用FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH解决了问题 - 我的应用程序没有使用机器内存,而且机器通常更有用.我希望能复制我在Linux上看到的改进.在Windows上有限制写入扇区大小的部分,我很满意这个限制我测量的增益量.

在Linux中有类似的方法吗?

asv*_*kau 6

你能提到的最接近你提到的Windows标志的等价物是用open(2)标志打开你的文件O_DIRECT | O_SYNC:

   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.

          A semantically similar (but deprecated) interface for block devices is
          described in raw(8).
Run Code Online (Sandbox Code Playgroud)

诚然,试图做这个标志的研究来证实这是你想要什么,我发现这个有趣的一块告诉你,无缓冲I/O是一个坏主意,莱纳斯将其描述为"脑损伤".根据你应该使用,madvise()而不是告诉内核如何缓存页面.因人而异.


Mar*_*rkR 6

您可以使用O_DIRECT,但在这种情况下,您需要自己执行块IO; 你必须以FS块大小和块边界的倍数写入(有可能它不是强制性的,但如果你不这样做,它的性能将会吸收x1000,因为每个未对齐的写入都需要先读取).

在不使用O_DIRECT的情况下,使用操作系统缓存停止块的另一种影响较小的方法是使用posix_fadvise(fd,offset,len,POSIX_FADV_DONTNEED).在支持它的Linux 2.6内核下,这会立即从缓存中丢弃(清除)块.当然,您需要首先使用fdatasync()等,否则块可能仍然是脏的,因此不会从缓存中清除.

在每次写入之后,fdatasync()和posix_fadvise(... POSIX_FADV_DONTNEED)可能是个坏主意,而是等到你做了一个合理的数量(50M,100M).

所以简而言之

  • 在每次(大量的)写入之后,
  • 调用fdatasync后跟posix_fadvise(... POSIX_FADV_DONTNEED)
  • 这会将数据刷新到光盘并立即将它们从操作系统缓存中删除,为更重要的事情留出空间.

一些用户发现像快速增长的日志文件这样的东西很容易从磁盘缓存中吹出"更有用"的东西,这会减少需要大量读取缓存的盒子上的缓存命中率,而且还能快速写入日志.这是此功能的主要动机.

但是,像任何优化一样

a)你不会那么需要它

b)不要这样做(还)