【问题标题】:What posix_fadvise() args for sequential file write?用于顺序文件写入的 posix_fadvise() 参数是什么?
【发布时间】:2016-10-27 06:48:54
【问题描述】:

我正在开发一个按顺序写入大文件(并且根本不读取)的应用程序,我想使用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() 写作?

【问题讨论】:

    标签: c optimization posix


    【解决方案1】:

    大多数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

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

    【讨论】:

    • 太棒了,这就是我需要让 utee (github.com/aktau/utee) 不破坏缓存但保持快速。谢谢!
    【解决方案2】:

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

    【讨论】:

    • 请注意 POSIX_FADV_NOREUSE 没有在 linux 内核中实现。
    【解决方案3】:

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

    您应该记住,虽然posix_fadvise 专门用于向内核提供有关未来文件使用模式的提示,但内核也有其他数据来帮助它。

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

    【讨论】:

      猜你喜欢
      • 2015-01-26
      • 2012-02-26
      • 2015-10-29
      • 1970-01-01
      • 2016-08-27
      • 2016-08-27
      • 1970-01-01
      • 2014-06-15
      • 1970-01-01
      相关资源
      最近更新 更多