什么posix_fadvise()args用于顺序文件写入?

时间:2010-09-20 21:44:06

标签: c optimization posix

我正在开发一个顺序写入大文件的应用程序(根本不读取),我想使用posix_fadvise()来优化文件系统的行为。

联机帮助页中的函数说明表明最合适的策略是POSIX_FADV_SEQUENTIAL。但是,Linux实现描述怀疑:

  

在Linux下,POSIX_FADV_NORMAL将预读窗口设置为支持设备的默认大小; POSIX_FADV_SEQUENTIAL将此大小加倍,POSIX_FADV_RANDOM完全禁用文件预读。

由于我只是在写数据(可能也会覆盖文件),所以我不希望有任何预读。我应该坚持使用POSIX_FADV_SEQUENTIAL还是使用POSIX_FADV_RANDOM来禁用它?

其他选项如POSIX_FADV_NOREUSE?或者可能根本不使用posix_fadvise()进行写作?

3 个答案:

答案 0 :(得分:37)

大多数posix_fadvise()标志(例如POSIX_FADV_SEQUENTIALPOSIX_FADV_RANDOM)都是有关预读而非写作的提示。

Linus herehere提供了一些关于获得良好的顺序写入性能的建议。我的想法是将文件分解为大型(8MB)窗口,然后循环执行:

  • write();
  • 写出窗口N.
  • 请求使用sync_file_range(..., SYNC_FILE_RANGE_WRITE)
  • 异步写出窗口N.
  • 等待用sync_file_range(..., SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER)
  • 完成窗口N-1的写出
  • 使用posix_fadvise(..., POSIX_FADV_DONTNEED)
  • 从页面缓存中删除窗口N-1

这样,您在页面缓存中永远不会有超过两个窗口的数据,但是当您填充下一部分时,仍然会让内核将部分页面缓存写入磁盘。

答案 1 :(得分:5)

这一切都取决于数据的时间局部性。如果您的应用程序在编写后不久就不需要数据,那么您可以使用POSIX_FADV_NOREUSE来避免写入缓冲区缓存(与O_DIRECT标记的方式类似open() })。

答案 2 :(得分:0)

就写入而言,我认为您可以依靠操作系统磁盘IO调度程序来做正确的事情。

您应该记住,虽然posix_fadvise专门用于提供有关未来文件使用模式的内核提示,但内核还有其他数据可以帮助解决这个问题。

如果您没有打开文件进行读取,则只需要在部分写入时读取块。如果你要将文件截断为0,那么它甚至不必这样做(你说你被覆盖了)。