高速缓存与缓冲区

这一节是本章计算题的主战场,考点高度集中在单缓冲与双缓冲的两个公式上。

这两个公式不需要背——它们都是从”一个缓冲区在被占用时,别人就不能用”这一句直接推出来的。下面把推导写清楚,公式自然就留下了。

机制

磁盘高速缓存

磁盘高速缓存在逻辑上属于磁盘,物理上则是驻留在内存中的盘块。

它有两种实现形式:① 在内存中开辟一个单独的存储空间作为磁盘高速缓存,大小固定;② 把未利用的内存空间作为一个缓冲池,供请求分页系统和磁盘 I/O 时共享——这种方式能随内存松紧自动伸缩,利用率更高。

为什么要引入缓冲区

教材给出四条理由,它们其实回答了四个不同的问题,分开记不容易混:

① 缓和 CPU 与 I/O 设备之间速度不匹配的矛盾。 这是最根本的一条:CPU 快、外设慢,中间加一层缓冲,双方就都不必迁就对方的节奏。

② 减少对 CPU 的中断频率,放宽对 CPU 中断响应时间的限制。 若没有缓冲,设备每准备好一个字符就要中断一次;有了缓冲区,可以攒满一批再中断一次。

③ 解决基本数据单元大小不匹配的问题。 例如发送方一次产生一个字符,接收方却要求以数据块为单位处理,缓冲区正好用来把小单元攒成大单元。

④ 提高 CPU 和 I/O 设备之间的并行性。 有了缓冲,设备可以一边输入下一块,CPU 一边处理上一块——这正是下面两个公式的全部来源。

单缓冲

系统只为这次 I/O 分配一个缓冲区。 设一块数据要经历三段时间:

  • :设备把一块数据送入缓冲区
  • :把数据从缓冲区搬到用户区
  • :CPU 处理这块数据

关键约束只有一条:缓冲区只有一个,所以在数据从缓冲区搬到用户区(耗时 )的这段时间里,设备不能往缓冲区里输入下一块——否则会把还没搬走的数据覆盖掉。

于是稳态下一轮的时间线是:

先花 把当前块从缓冲区搬到用户区(这段时间设备只能干等);搬完之后缓冲区空了,设备立刻开始输入下一块(),与此同时 CPU 处理刚搬到用户区的这一块()——这两件事用的是不同的资源,可以并行,因此只需等其中较慢的那个。

单缓冲处理一块数据的时间

双缓冲

系统分配两个缓冲区,于是那条”搬运时设备必须干等”的约束消失了:设备可以往缓冲区 2 输入,同时缓冲区 1 的数据被搬到用户区并处理。

此时两条流水线完全并行:设备侧每轮花 (输入一块);CPU 侧每轮花 (搬一块 + 处理一块)。整个系统的节奏由较慢的那一侧决定:

双缓冲处理一块数据的时间

两个公式对照着看,差别一目了然:单缓冲的 在 外面(它挡住了设备),双缓冲的 被塞进了 里面(它与设备输入并行了)。 这就是多一个缓冲区买来的东西。

循环缓冲与缓冲池

循环缓冲把多个缓冲区组织成一个循环队列,并设置输入指针与输出指针,适合”输入输出速度基本匹配但存在波动”的场合。

缓冲池是更通用的方案,它由三个队列和四种工作缓冲区组成:

三个队列:空缓冲队列、输入队列(装满输入数据的缓冲区)、输出队列(装满输出数据的缓冲区)。

四种工作缓冲区:收容输入(hin)、提取输入(sin)、收容输出(hout)、提取输出(sout)。

它们的命名有规律:“收容”是往缓冲区里放,“提取”是从缓冲区里取;“输入”是设备→内存方向,“输出”是内存→设备方向。两两组合就是四种。

缓冲池与单纯的多缓冲区的区别在于”公用”:缓冲池中的缓冲区可供多个进程共享,且既能用于输入也能用于输出,因此利用率远高于为每次 I/O 单独分配。

边界

缓冲区与高速缓存的区别

这是本节最重要的一条概念辨析,判据是”里面的数据在源头还有没有”:

高速缓存中存放的是低速设备上某些数据的复制品。 原件仍在低速设备上——高速缓存里有的,低速设备里一定也有。它的目的是下次再访问同一份数据时不必再去慢设备取,赌的是局部性原理。

缓冲区中存放的是低速设备与高速设备之间正在传输的数据。 这些数据在源头不一定有副本——它可能是刚从键盘敲进来、还没写到任何地方的字符,也可能是即将送去打印、之后就不再需要的内容。它的目的是抹平速度差与单位差,赌的不是重复访问,而是双方节奏不同。

一句话判据:高速缓存是”留一份副本以备再用”,缓冲区是”过路的数据在这里歇一脚”。

缓冲区管理最核心的问题是同步

疑问点:缓冲区管理需要重点考虑的问题

  1. 缓冲区管理者重要考虑的问题是( )。 A. 选择缓冲区的大小 B. 决定缓冲区的数量 C. 实现进程访问缓冲区的同步 D. 限制进程的数量

答案 C。

缓冲区本质上是一个生产者—消费者共享资源:设备是生产者,进程是消费者(输出时反过来)。必须保证”缓冲区空时消费者不能取、满时生产者不能放”,并且多个执行流不能同时读写同一个缓冲区。

A 和 B 确实会影响性能,但它们是调优参数,不是正确性问题。 大小和数量选得不好只是慢一点;同步做错了会直接读到错数据或丢数据。 选择题问”重要考虑的问题”,正确性永远优先于性能。

D 限制进程的数量与缓冲区管理无关,那是多道程序度的话题。

单缓冲计算题的标准解法

疑问点:单缓冲下处理一块数据的总时间

  1. 设从磁盘将一块数据传送到缓冲区所用的时间为 80μs,将缓冲区中的数据传送到用户区所用的时间为 40μs,CPU 处理一个数据块所用的时间为 30μs。若有多块数据需要处理,并采用单缓冲区传送某磁盘数据,则处理一块数据所用的总时间为( )。 A. 120μs B. 110μs C. 150μs D. 70μs

答案 A。 直接套公式:选项 C(150μs)是最有诱惑力的错误——它等于 ,即完全串行,等于假设缓冲区没起任何作用。看到这个选项就应该警觉:既然题目专门说了”采用单缓冲区”,答案就一定要体现出重叠。

题干里”若有多块数据需要处理”这句话是在提示求的是稳态周期,不是第一块的完整耗时。第一块之前还要多等一次输入 ,最后一块之后还有收尾,题目问 块总时间时才需要补首尾。

哪些场合需要缓冲

疑问点:需要使用缓冲技术的 I/O 操作

  1. 考虑单用户计算机上的下列 I/O 操作,需要使用缓冲技术的是( )。 I. 图形用户界面下使用鼠标 II. 多任务操作系统下的磁盘驱动器(假设没有设备预分配) III. 包含用户文件的磁盘驱动器 IV. 使用存储器映射 I/O,直接和总线相连的图形卡

答案:四项全选。

I 鼠标——鼠标移动会持续产生大量事件,必须有事件队列把它们暂存下来,否则程序来不及处理的事件就丢了。

II 多任务下的磁盘驱动器——多个进程同时发请求,需要缓冲来协调排队。

III 包含用户文件的磁盘驱动器——需要块缓存来减少实际的磁盘访问。

IV 存储器映射 I/O 的图形卡——这一项最容易被排除,也是本题的考点。看到”直接和总线相连""存储器映射 I/O”,直觉会认为”既然是直连、又能用访存指令直接操作,就不需要缓冲了”。

但这个推理混淆了两件事:“存储器映射 I/O”描述的是访问方式(用访存指令而非专门的 I/O 指令,见 5.1.1),它并不否定缓冲的必要性。图形卡恰恰是双缓冲的经典应用场景:显示当前这一幅图的同时准备下一幅,画面才不会撕裂或闪烁。

这条推广开来是本题真正的教训:访问方式与是否需要缓冲,是两个正交的问题。

对照速查

高速缓存缓冲区
里面是什么低速设备上数据的复制品正在传输的数据
源头还有没有一定有(原件在低速设备上)不一定有
目的下次再访问时不必去慢设备取抹平速度差与单位差
依赖局部性原理双方节奏不同
引入缓冲区的四个目的
①缓和 CPU 与 I/O 设备速度不匹配
②减少对 CPU 的中断频率,放宽中断响应时间限制
③解决基本数据单元大小不匹配
④提高 CPU 与 I/O 设备的并行性
公式表达式为什么
单缓冲搬运时设备必须干等,故 在 外
双缓冲设备侧 与 CPU 侧 完全并行
缓冲池内容
三个队列空缓冲队列、输入队列、输出队列
四种工作缓冲区收容输入 hin、提取输入 sin、收容输出 hout、提取输出 sout
命名规律”收容”=放进去,“提取”=取出来;输入=设备→内存,输出=内存→设备

考点

  • 缓冲区 vs 高速缓存:判据是”源头还有没有副本”
  • 引入缓冲区的四个目的,注意②是”减少中断频率”
  • 单缓冲 ;双缓冲 ——记住 在不在 里
  • 计算题完全串行的那个选项是陷阱(本题的 150μs)
  • 缓冲区管理最核心的是同步,不是大小和数量
  • 存储器映射 I/O 不否定缓冲的必要性;图形卡是双缓冲的经典场景
  • 缓冲池的三队列四工作缓冲区及其命名规律

链接