[操作系统] Linux IO模式(缓存IO、直接IO)

参考博客:

https://sccarterrans.github.io/IO%E6%A8%A1%E5%9E%8B-%E7%BC%93%E5%AD%98IO%E4%B8%8E%E7%9B%B4%E6%8E%A5IO/

https://cloud.tencent.com/developer/news/406991

https://www.cnblogs.com/orange-CC/p/13572789.html

1.IO设备与内存间数据传输方式

PIO(Programming Input/Output) 由CPU执行IO指令,控制整个数据传输过程。是早期数据传输方式,CPU占有率高(但利用率其实不高),不适合传输大量数据。

PIO还可以分为轮询和中断两种方式,轮询:CPU从一开就循环询问IO是否可用(尝试抢占IO);中断:CPU向IO设备发出请求,当设备就绪后向CPU发出中断信号,CPU再返回执行IO操作。

DMA(Direct Memory Access) 不经过CPU直接进行内存访问。具体来讲,CPU仅负责向DMA控制器写入指令,之后DMA负责处理数据传送,传送完毕后再向CPU返回信息。

2.缓存与直接IO

缓存IO:数据通过DMA拷贝到内核高速缓存页(注:内存缓存,由RAM中的物理页组成,每一页对应磁盘中多个块,这样组织可以达到更高的访问速率),再从高速缓存页拷贝到用户空间应用缓存

直接IO:数据通过DMA直接拷贝到用户空间应用缓存

Q:DMA已经不需要大量占用CPU,为什么还要搞一个缓存IO,多拷贝一次数据岂不是多此一举?

A:在很多情境下程序会返回请求同一块数据,如果是直接IO,则会反复进行磁盘读取而造成长时间等待,若有系统高速缓存页则可以命中大部分读取请求,减少磁盘访问。

Q:高速缓存页本质上也是物理内存,其优势是什么,为什么缓存不交给程序自行管理?

A:高速缓存页有对应磁盘块的信息表,可以快速查找是否命中。程序的确可以自行管理缓存,高速缓存是系统提供的一个“基础服务”,必要时可以自行采用其他内存管理手段。

3.缓存IO

绝大数系统的默认模式(也是绝大数服务组件的默认模式)。

3.1 读操作

检查内核高速缓存页是否能命中读取目标,命中直接返回,否则先读取后再返回。

3.2 写操作

用户进程调用systemCall以DMA方式将用户空间的缓存数据拷贝到内核空间高速页缓存中,随后再拷贝到用户空间缓存。写操作缓存刷新策略有“写透缓存”和“回写”两种。

写透缓存:写操作更新完内核缓存后立即更新磁盘文件,可以保证缓存一致性。

回写:写操作更新完内核缓存后并不立即更新磁盘文件,而是先标记被写入页面为脏页面,将其加入脏链表中。系统中的守护进程“回写进程”会再随后将脏页刷新进磁盘中。

Q:回写进程会在什么时候刷新脏页?

A:a.每隔一段时间回写进程会进行刷新操作,b.当缓存满或空闲内存不足时回写进程会被启动进行写操作(随后会进行缓存回收)c.用户进程调用sync或fsync等操作(注意fflush是刷新用户缓存到系统缓存) d.脏页存在时间超过阈值。

3.3 缓存回收

其作用是清除缓存中的数据,为更重要的数据提供空闲页以及减小内存占用。

一般情况下系统会选择干净页进行回收,除非缓存被写满(此时会强制启动回写操作释放干净页)。

回收策略:LRU(最近最少使用)。

双链策略:改进的LRU,维护两张链表:活跃链表和非活跃链表。回收非活跃链表中的数据。

3.4 优缺点

优点:减少磁盘访问,提升读写性能(注:根据Redis作者的观点,主要提升的是读性能)。

缺点:某些情况下,因为需要多次数据拷贝操作,反而会更加占用CPU和浪费内存空间(比如确定只需要读入一次的数据)。

4. 直接IO

绕过内核缓存区,由DMA直接读取磁盘数据到用户空间。一般是因为需要自行管理缓冲区或有特殊原因。

linux ddf命令、fio压测工具、腾讯云的cosfs(基于s3fs)中都有 --directio 参数可供选择,另外linux系统的open函数由O_DIRECT选项,以达到使用直接IO的目的。

优点:减少拷贝次数,降低开销。

缺点:若管理不当则会导致效率降低。

posted @ 2021-10-12 11:53  Cheung-10  阅读(156)  评论(0)    收藏  举报