什么posix_fadvise()args用于顺序文件写入?
我正在开发一个顺序写入大文件(并且根本不读取)的应用程序,我想使用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()
来写作?
这一切都取决于数据的时间局部性。 如果您的应用程序在写入后不久就不需要数据,那么您可以使用POSIX_FADV_NOREUSE
来避免写入缓冲区缓存(与open()
的O_DIRECT
标志类似)。
大多数posix_fadvise()
标志(例如POSIX_FADV_SEQUENTIAL
和POSIX_FADV_RANDOM
)都是关于readahead而不是写入的提示。
Linus 在这里和这里提出了一些关于获得良好的顺序写入性能的建议。 想法是将文件分解为大型(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的sync_file_range(..., SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER)
- 使用
posix_fadvise(..., POSIX_FADV_DONTNEED)
从页面缓存中删除窗口N-1
这样,页面缓存中的数据永远不会超过两个窗口,但是当您填充下一部分时,仍然会让内核将部分页面缓存写入磁盘。
就写入而言,我认为您可以依靠操作系统磁盘IO调度程序来做正确的事情。
您应该记住,虽然posix_fadvise
专门提供有关未来文件使用模式的内核提示,但内核还有其他数据来帮助它。
如果你没有打开文件进行读取,那么它只需要在部分写入时读取块。 如果你要将文件截断为0,那么它甚至不必这样做(你说你被覆盖了)。