乐趣区

Linux内核学习笔记八Page-Cache与Page回写

Page cache 是通过将磁盘中的数据缓存到内存中,从而减少磁盘 I / O 操作,从而提高性能。此外,还要确保在 page cache 中的数据更改时能够被同步到磁盘上,后者被称为 page 回写(page writeback)。一个 inode 对应一个 page cache 对象,一个 page cache 对象包含多个物理 page。

对磁盘的数据进行缓存从而提高性能主要是基于两个因素:第一,磁盘访问的速度比内存慢好几个数量级(毫秒和纳秒的差距)。第二是被访问过的数据,有很大概率会被再次访问。

Page Cache
Page cache 由内存中的物理 page 组成,其内容对应磁盘上的 block。page cache 的大小是动态变化的,可以扩大,也可以在内存不足时缩小。cache 缓存的存储设备被称为后备存储(backing store),注意我们在 block I/ O 一文中提到的:一个 page 通常包含多个 block,这些 block 不一定是连续的。

读 Cache
当内核发起一个读请求时(例如进程发起 read()请求),首先会检查请求的数据是否缓存到了 page cache 中,如果有,那么直接从内存中读取,不需要访问磁盘,这被称为 cache 命中(cache hit)。如果 cache 中没有请求的数据,即 cache 未命中(cache miss),就必须从磁盘中读取数据。然后内核将读取的数据缓存到 cache 中,这样后续的读请求就可以命中 cache 了。page 可以只缓存一个文件部分的内容,不需要把整个文件都缓存进来。

写 Cache
当内核发起一个写请求时(例如进程发起 write()请求),同样是直接往 cache 中写入,后备存储中的内容不会直接更新。内核会将被写入的 page 标记为 dirty,并将其加入 dirty list 中。内核会周期性地将 dirty list 中的 page 写回到磁盘上,从而使磁盘上的数据和内存中缓存的数据一致。

Cache 回收
Page cache 的另一个重要工作是释放 page,从而释放内存空间。cache 回收的任务是选择合适的 page 释放,并且如果 page 是 dirty 的,需要将 page 写回到磁盘中再释放。理想的做法是释放距离下次访问时间最久的 page,但是很明显,这是不现实的。下面先介绍 LRU 算法,然后介绍基于 LRU 改进的 Two-List 策略,后者是 Linux 使用的策略。

LRU 算法
LRU(least rencently used) 算法是选择最近一次访问时间最靠前的 page,即干掉最近没被光顾过的 page。原始 LRU 算法存在的问题是,有些文件只会被访问一次,但是按照 LRU 的算法,即使这些文件以后再也不会被访问了,但是如果它们是刚刚被访问的,就不会被选中。

Two-List 策略
Two-List 策略维护了两个 list,active list 和 inactive list。在 active list 上的 page 被认为是 hot 的,不能释放。只有 inactive list 上的 page 可以被释放的。首次缓存的数据的 page 会被加入到 inactive list 中,已经在 inactive list 中的 page 如果再次被访问,就会移入 active list 中。两个链表都使用了伪 LRU 算法维护,新的 page 从尾部加入,移除时从头部移除,就像队列一样。如果 active list 中 page 的数量远大于 inactive list,那么 active list 头部的页面会被移入 inactive list 中,从而位置两个表的平衡。
————————————————
版权声明:本文为 CSDN 博主「胡 LiuJia」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/damonti…

退出移动版