Linux中的无缓冲I / O.

时间:2011-01-16 05:16:40

标签: linux file-io filesystems fopen

我写了很多很多数据,这些数据几周都不会再读了 - 因为我的程序运行机器上的可用内存量(显示为'free'或'top')下降非常快,金额我的应用程序使用的内存不会增加 - 其他进程使用的内存量也不会增加。

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

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

在Linux中有类似的方法吗?

3 个答案:

答案 0 :(得分: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).

当然,尝试对此标志进行研究以确认它是您想要的,我发现this interesting piece告诉您无缓冲的I / O是一个坏主意,Linus将其描述为“脑损坏”。根据你应该使用madvise()来告诉内核如何缓存页面。 YMMV。

答案 1 :(得分:6)

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

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

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

所以简而言之

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

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

然而,像任何优化一样

a)你不会需要它

b)不要(尚)

答案 2 :(得分:2)

  

当我的程序运行时,机器上的可用内存量会很快下降

为什么这是一个问题?可用内存是没有用于任何有用目的的内存。当它用于缓存数据时,至少有可能它会有用。

如果你的某个程序请求更多内存,文件缓存将是第一件事。 Linux知道它可以随时从磁盘重新读取数据,因此它只会收获内存并为其提供新的用途。

在刷新写入磁盘之前,默认情况下Linux默认等待大约30秒(这是以前的值)。您可以通过拨打fsync()加快速度。但是,一旦将数据写入磁盘,将数据缓存保留在内存中的成本几乎为

当您写入文件并且不从中读取文件时,Linux可能会猜测此数据最好丢弃,而不是其他缓存数据。因此,除非您已经确认这是性能问题,否则不要浪费精力进行优化。