linux系统编程——文件IO——给内核提供建议

1. 什么是提供建议

通过 madvise() ,进程可以给内核提供建议,以提高文件IO性能。

2. 对映射用法提供建议

int madvise(void *addr, size_t len , int advice);

@len : 若为0,则建议会应用到addr开始的整个映射。
@advice:描述该建议:
POSIX只规定了建议是什么意思,没规定建议的结果,2.6版本内核如下
MADV_NORMAL : 无建议,按照一般方式处理
内核的行为不变,执行适当数量的预读操作
MADV_RANDOM : 以随机(非顺序)方式访问指定页面
内核禁用预读,每次实际读取操作时会进行最少量的读数据
MADV_SEQUENTIAL : 以顺序方式(从低地址到高地址)访问页面
内核会积极进行预读
MADV_WILLNEED : 在不久的将来,程序将访问页面
内核会发起预读,开始将指定页面读取到内存
MADV_DONTNEED : 不久的将来,程序不打算访问页面
内核会释放特定页面相关任何资源,并丢弃任何被修改且未同步的页面,随后对映射数据的访问将导致数据的页面从支持文件被读进来。

典型用法:
以顺序方式访问内存区域[addr, addr+len]

ret = madvise(addr, len, MADV_SEQUENTIAL);

3. 对一般文件IO用法提供建议

3.1 posix_fadvise()

int posix_fadvise(int fd, off_t offset, off_t len, int advice);

将[offset, offset + len] 范围内的建议提供给内核。若len为0,则将应用到[offset, length of file]范围的内存。
典型用法是将 offset len 都指定为0,则建议会应用到整个文件。
@advice
POSIX_FADV_NORMAL:一般处理
内核正常预读
POSIX_FADV_RANDOM:随机读
内核禁用预读,每次只读取最少量数据
POSIX_FADV_SEQUENTIAL:顺序读
内核积极使用预读,将预读窗口加大
POSIX_FADV_WILLNEED:不久将来,将访问所指定范围
内核发起预读
POSIX_FADV_NOREUSE:不久将来,将访问所指定范围,但只访问一次
同POSIX_FADV_WILLNEED,新的内核可能进行优化
POSIX_FADV_DONTNEED:不久的将来,程序不打算访问页面
内核在指定的范围中从页缓存收回被缓存的任何数据。

int ret = posix_fadvice(fd, 0, 0, POSIX_FADV_RANDOM);

3.2 readahead

readahead 是 linux特有的,行为和 posix_fadvise 的 POSIX_FADV_WILLNEED 一致

4. 建议是廉价的

由于磁盘相对于cpud太慢了,所以小小的建议可以提供莫大的好处。
如,读文件前,进程可以提供 POSIX_FADV_WILLNEED,让内核进行预读,IO将在后台进行,当程序访问文件时,IO操作能顺序完成。
当读取或写入许多数据后,进程可以提供 POSIX_FADV_DONTNEED,让内核从页面回收特定数据块,一个流媒体程序会不断填充页缓存,
所以若程序不打算再次访问这些数据,最好定期将数据回收。
读整个文件的进程可以提供 POSIX_FADV_SEQUENTIAL,让内存积极预读。
而随机读文件,以查找数据,则提供 POSIX_FADV_RANDOM.

posted on 2021-08-24 00:06  开心种树  阅读(185)  评论(0编辑  收藏  举报