1. 从22年44题说起:这道题到底在考什么
408考卷里,计算机组成原理的I/O章节一直是很多人的心结。原因不复杂:这章的概念密度高,DMA、中断、程序查询三种控制方式搅在一起,再加上外存那道磁道扇区计算题,稍不留神就丢分。22年44题就是典型代表,它把两个看似不搭的知识点揉进了一道题里——一边是DMA方式下主机与I/O设备之间的信息传送控制,另一边是磁盘上磁道、扇区的地址计算。
我第一次做这道题的时候,第一反应是"这俩东西怎么凑一块了"。后来把题目拆开看才明白,命题人其实是在考一个完整的链路:数据从磁盘上某个具体的物理位置读出来,经过DMA控制器直接送进主存,整个过程CPU几乎不插手。你要算清楚数据在磁盘上的位置,还要说清楚DMA是怎么把这个位置的数据搬进内存的。这两件事单独看都不难,但放在一起,就要求你对"数据从哪来、怎么走、谁在管"有一条清晰的线。
这篇文章就是围绕这条线展开的。我会先把DMA方式的工作机制讲透,再把磁道扇区的计算逻辑拆干净,最后把两者怎么在同一道题里配合起来说清楚。不管你是正在备考408的考生,还是想重新梳理组成原理基础的开发者,这篇内容都能帮你把这块知识从"背过"变成"真懂"。
需要先说明一点:408的题目每年都在变,但核心考点的底层逻辑是稳定的。22年44题考的是DMA和磁盘地址计算,24年45题又换了个角度考类似的东西。你把这套逻辑吃透,换什么题面都能应对。
2. DMA方式的工作机制:为什么它能绕开CPU搬数据
2.1 三种I/O控制方式的本质区别
要理解DMA,得先知道它解决了什么问题。主机和I/O设备之间传数据,最原始的方式是程序查询方式:CPU不断读取设备状态寄存器,设备准备好了就传一个字节,没准备好就继续等。这种方式的问题很明显——CPU的时间全耗在轮询上了,设备慢的时候CPU就在那儿空转。
稍微好一点的是中断方式:CPU不用一直等,设备准备好之后发中断信号,CPU响应中断再传数据。但中断方式有个硬伤——每传一个字节或一个字,都要打断CPU一次,保存现场、执行中断服务程序、恢复现场。传大量数据的时候,这个开销累积起来非常可观。
DMA方式(Direct Memory Access,直接存储器访问)的思路完全不同:既然CPU只是当搬运工,那干脆找个专门的硬件来搬。DMA控制器(DMAC)接管了数据传送的控制权,数据直接在设备和主存之间流动,CPU只需要在开始的时候告诉DMAC"从哪读、写到哪、读多少",然后在结束的时候收个通知就行。
这三种方式的对比可以用一个生活场景来理解:程序查询像是你亲自去快递站一趟趟取包裹;中断方式像是快递员每次到了给你打电话让你下楼拿;DMA方式则是你给了快递员一把钥匙,让他直接把包裹放进你家储物间,放完了再告诉你一声。
2.2 DMA控制器的内部结构与数据通路
DMAC不是个黑盒子,它内部有几个关键部件需要搞清楚。地址寄存器存放当前要访问的主存地址,每传一个数据就自动加一(或减一)。字计数器记录还剩多少数据没传,每传一个就减一,减到零表示传送完成。控制逻辑负责协调整个传送过程,包括向CPU发总线请求、控制数据读写等。此外还有状态寄存器和控制寄存器,用来反映DMAC的工作状态和接收CPU的命令。
数据通路是这样的:当DMAC获得总线控制权后,I/O设备的数据通过数据总线直接写入主存,或者主存的数据直接送到I/O设备。整个过程CPU不参与数据搬运,只在这条通路建立之前和拆除之后做该做的事。
这里有个容易混淆的点:DMA传送的是数据,不是控制信息。CPU和DMAC之间的交互(比如CPU告诉DMAC传送参数、DMAC向CPU报告完成)走的是另一套通路,通常是通过系统总线访问DMAC的寄存器。数据通路和控制通路是分开的,这一点在理解DMA的工作流程时很关键。
2.3 DMA的三种传送方式及其适用场景
DMA并不是只有一种工作模式,根据DMAC和CPU对总线的占用方式,分为三种:
停止CPU访存方式:DMAC一旦开始传送,就独占总线,CPU在此期间不能访问主存。这种方式控制简单,适合数据块传送速度要求高的场景,但CPU在此期间基本被"冻结"了。
周期挪用方式(也叫周期窃取):DMAC趁CPU不访问主存的那些总线周期插入一次DMA传送。这种方式对CPU影响小,但DMAC需要等待可用的总线周期,传送速度受限于总线的空闲程度。
交替访存方式:把CPU的工作周期分成两半,一半给CPU,一半给DMA,两者交替使用总线。这种方式不需要总线请求和响应,效率高,但时序控制复杂,对CPU的时间划分要求严格。
408考试里最常考的是前两种。周期挪用方式尤其重要,因为它涉及"DMA传送是否影响CPU执行"这个经典问题。答案是不影响CPU的指令执行逻辑,但会占用总线周期,导致CPU访存变慢。
2.4 DMA传送的完整流程:从预处理到后处理
一次完整的DMA传送分为三个阶段:
预处理阶段:CPU执行几条指令,把要传送的数据在主存中的起始地址、要传送的数据长度、传送方向(读还是写)等信息写入DMAC的各个寄存器。同时,CPU还要对I/O设备进行初始化,比如启动磁盘寻道。这个阶段CPU是主动参与的。
数据传送阶段:DMAC接管总线,在I/O设备和主存之间直接传送数据。每传一个数据,地址寄存器加一,字计数器减一。这个阶段CPU完全不参与,可以继续执行其他程序(除非总线被完全占用)。
后处理阶段:当字计数器减到零,DMAC向CPU发出中断请求。CPU响应中断后,检查传送是否出错,然后进行必要的收尾工作,比如把DMAC的状态信息读出来、准备下一次传送等。
注意:预处理和后处理都是CPU用程序完成的,只有中间的数据传送阶段是DMAC硬件完成的。考试里问"DMA方式下CPU参与哪些工作",答案就是预处理和后处理,不包括数据搬运本身。
3. 磁盘的物理结构:磁道、扇区与地址计算
3.1 磁盘的物理组织方式
磁盘的盘面是一层磁性材料,数据就记录在上面。盘面被划分成若干个同心圆,每个同心圆叫一个磁道(track)。磁道从外向内编号,最外圈是0道。每个磁道又被分成若干段,每段叫一个扇区(sector),扇区是磁盘读写的最小单位。
一个盘片有两个面,每个面都可以记录数据。多个盘片叠在一起组成盘组,所有盘面上相同位置的磁道构成一个柱面(cylinder)。比如所有盘面的0道合起来就是0柱面。柱面的概念很重要,因为磁盘寻道时,磁头臂移动一次就定位到一个柱面,然后所有盘面的对应磁道都可以读写,不需要额外移动磁头臂。
磁盘的地址通常用三个参数表示:柱面号(C)、磁头号(H)、扇区号(S)。这就是所谓的CHS寻址方式。知道这三个参数,就能唯一确定磁盘上的一个扇区。
3.2 磁道与扇区的计算逻辑
磁盘容量计算是408的常客。基本公式是:
磁盘总容量 = 盘面数 × 每面磁道数 × 每道扇区数 × 每扇区字节数
这个公式看起来简单,但题目往往会绕几个弯。比如告诉你磁盘转速、数据传输率,让你反推每道扇区数;或者告诉你平均寻道时间、旋转延迟,让你算平均存取时间。
平均存取时间的计算是另一个高频考点:
平均存取时间 = 平均寻道时间 + 平均旋转延迟 + 数据传输时间
平均寻道时间题目一般直接给出。平均旋转延迟是磁盘转半圈的时间,如果转速是r转/分钟,那么转一圈的时间是60/r秒,平均旋转延迟就是30/r秒。数据传输时间取决于要读的数据量和数据传输率。
这里有个细节容易被忽略:数据传输时间在有些题目里可以忽略不计,因为相比寻道和旋转延迟,它通常小得多。但题目如果明确给了数据传输率,那就得老老实实算进去。
3.3 扇区地址的定位过程
给定一个逻辑块号,怎么找到对应的CHS地址?这是磁盘计算题的核心操作。
假设磁盘有N个盘面,每个盘面有T个磁道,每个磁道有S个扇区。逻辑块号从0开始编号,编号顺序通常是:先在同一磁道内按扇区递增,然后换磁头(盘面),最后换柱面。
具体计算步骤:
- 计算柱面号:
C = 逻辑块号 / (每柱面扇区数),其中每柱面扇区数 = 盘面数 × 每道扇区数 - 计算柱面内的偏移:
offset = 逻辑块号 % (每柱面扇区数) - 计算磁头号:
H = offset / 每道扇区数 - 计算扇区号:
S = offset % 每道扇区数
这个计算过程在22年44题里就出现了。题目给了一个逻辑块号,要求算出对应的柱面号、磁头号和扇区号。很多人丢分不是因为不会算,而是因为编号顺序搞反了——到底先换扇区还是先换磁头,先换磁头还是先换柱面,这个顺序必须和题目的约定一致。
提示:408题目里通常会在题面明确说明编号顺序。如果没有说明,默认按"扇区→磁头→柱面"的顺序递增,也就是低地址位是扇区号,中间是磁头号,高位是柱面号。
3.4 磁盘访问时间与DMA的衔接点
磁盘读写一个扇区的过程是这样的:首先磁头臂移动到指定柱面(寻道时间),然后等待指定扇区旋转到磁头下方(旋转延迟),最后开始读写数据(数据传输)。这三个阶段里,数据传输阶段就是DMA发挥作用的地方。
当磁头定位到目标扇区后,磁盘控制器开始读取数据。读出来的数据不会经过CPU,而是由DMA控制器直接写入主存。磁盘控制器每读出一个字(或一个字节),就向DMAC发一个请求,DMAC获得总线后把这个字写入主存对应的地址。
这就是22年44题把两个知识点串起来的地方:你先要算出数据在磁盘上的物理位置,然后要说明DMA是怎么把这个位置的数据搬到主存里的。前者考的是磁盘地址计算,后者考的是DMA的工作机制。
4. 22年44题的完整拆解与解题链路
4.1 题目信息的提取与转化
22年44题的题面通常会给出一组磁盘参数,比如盘面数、每面磁道数、每道扇区数、扇区大小,然后给出一个逻辑块号,要求计算对应的CHS地址。同时,题目会描述一个DMA传送场景,要求说明DMA控制器在这个过程中做了什么。
拿到题目后,第一步是把所有参数列出来,明确哪些是已知量、哪些是待求量。这一步看起来简单,但很多人因为漏看了一个参数或者把单位搞混了而失分。比如扇区大小给的是字节数,但数据传输率给的是字节/秒,计算的时候要注意单位统一。
第二步是确定逻辑块号到CHS的映射规则。如果题目没有明确说明,就按默认的"扇区→磁头→柱面"顺序处理。如果题目给了映射规则,就严格按照题目的规则来。
第三步是计算。把逻辑块号除以每柱面扇区数得到柱面号,余数再除以每道扇区数得到磁头号,最后的余数就是扇区号。计算过程中要注意整数除法和取余的运算顺序。
4.2 DMA传送过程的逐步分析
题目通常会问:从磁盘读出这个扇区的数据并写入主存,DMA控制器需要完成哪些操作?
完整的回答应该包括:
- 预处理阶段:CPU初始化DMAC,把主存起始地址、传送字数、传送方向(从磁盘读到主存)写入DMAC的寄存器。同时CPU启动磁盘控制器,发出读命令。
- 寻道与旋转等待:磁盘控制器控制磁头臂移动到目标柱面,等待目标扇区旋转到磁头下方。这个阶段DMAC还没有开始数据传送。
- DMA请求与响应:当扇区数据开始读出时,磁盘控制器向DMAC发出DMA请求。DMAC向CPU发出总线请求(HRQ),CPU在当前总线周期结束后发出总线响应(HLDA),DMAC获得总线控制权。
- 数据传送:磁盘控制器把读出的数据放到数据总线上,DMAC把主存地址放到地址总线上,发出写命令,数据写入主存。每传一个字,DMAC的地址寄存器加一,字计数器减一。
- 传送结束:字计数器减到零,DMAC释放总线,向CPU发出中断请求。CPU响应中断,进行后处理。
这个流程里,第3步和第4步是DMA的核心。很多人只写了"DMAC控制数据传送",但没写清楚总线请求和响应的过程,也没写清楚地址寄存器和字计数器的变化,这样答题是不完整的。
4.3 答题时最容易丢分的三个地方
第一个丢分点:CHS计算顺序搞反。有些人习惯性地先算磁头号再算扇区号,结果和题目的编号规则对不上。记住,默认顺序是扇区号变化最快,磁头号次之,柱面号变化最慢。
第二个丢分点:DMA流程写得不完整。只写"DMAC控制数据从磁盘传到主存"是不够的,必须写出预处理、总线请求与响应、数据传送、后处理这几个阶段。尤其是总线请求和响应,这是DMA区别于其他I/O方式的关键。
第三个丢分点:忽略磁盘寻道和旋转延迟。题目如果问的是"从发出读命令到数据全部写入主存需要多长时间",那就必须把寻道时间、旋转延迟和数据传输时间都算进去。只算DMA传送时间是不对的。
4.4 从22年44题到24年45题的迁移思路
24年45题考了类似的知识点,但题面换了。这说明408的命题风格是"换汤不换药"——核心考点不变,只是换了个场景或者换了个问法。
迁移的思路是这样的:不管题目怎么变,你都要抓住两条线。一条是数据在哪里——磁盘上的物理地址怎么算;另一条是数据怎么走——DMA怎么把数据从磁盘搬到主存。这两条线交叉的地方,就是命题人最喜欢出题的地方。
比如24年45题可能换成了"从主存写入磁盘"的方向,那DMA的传送方向就反过来了,但流程还是一样的。或者换成了"多个扇区连续传送",那字计数器的初值就变成了扇区数乘以每扇区字数,地址寄存器的变化还是一样的。
5. 磁道扇区计算题的通用解题框架
5.1 参数识别与单位统一
拿到任何一道磁盘计算题,先把所有参数列出来,标注单位。常见的参数包括:
| 参数 | 常见单位 | 注意事项 |
|---|---|---|
| 盘面数 | 个 | 注意是盘面数不是盘片数,一个盘片有两个面 |
| 每面磁道数 | 个 | 也叫柱面数,因为每个盘面磁道数等于柱面数 |
| 每道扇区数 | 个 | 所有磁道的扇区数通常相同 |
| 扇区大小 | 字节 | 常见512B或4KB |
| 转速 | 转/分钟 | 计算旋转延迟时要换算成秒 |
| 数据传输率 | 字节/秒 | 计算数据传输时间时用 |
| 平均寻道时间 | 毫秒 | 题目一般直接给出 |
单位统一是计算正确的前提。转速是转/分钟,但旋转延迟要的是秒,所以要先除以60。数据传输率如果是MB/s,扇区大小是字节,计算时间的时候要注意换算。
5.2 逻辑地址到物理地址的映射
逻辑块号到CHS的映射是磁盘计算题的核心操作。通用的计算模板:
每柱面扇区数 = 盘面数 × 每道扇区数 柱面号 = 逻辑块号 / 每柱面扇区数 柱面内偏移 = 逻辑块号 % 每柱面扇区数 磁头号 = 柱面内偏移 / 每道扇区数 扇区号 = 柱面内偏移 % 每道扇区数这个模板适用于默认的"扇区→磁头→柱面"编号顺序。如果题目给了不同的编号顺序,比如"磁头→扇区→柱面",那就把对应的除数和取余对象换一下。
举个例子:假设磁盘有4个盘面,每面100个磁道,每道16个扇区。逻辑块号500对应的CHS是多少?
每柱面扇区数 = 4 × 16 = 64 柱面号 = 500 / 64 = 7 柱面内偏移 = 500 % 64 = 52 磁头号 = 52 / 16 = 3 扇区号 = 52 % 16 = 4
所以逻辑块号500对应的是7柱面、3磁头、4扇区。
5.3 存取时间的分段计算
存取时间的计算要分三段:寻道时间、旋转延迟、数据传输时间。
寻道时间:题目一般给平均寻道时间,直接用。
旋转延迟:平均旋转延迟 = 转半圈的时间 = 60 / (2 × 转速)。如果转速是7200转/分钟,平均旋转延迟 = 60 / (2 × 7200) = 1/240秒 ≈ 4.17毫秒。
数据传输时间:要读的数据量除以数据传输率。如果读一个扇区,数据量就是扇区大小。
总存取时间 = 平均寻道时间 + 平均旋转延迟 + 数据传输时间。
注意:有些题目问的是"平均存取时间",有些问的是"最坏情况存取时间"。最坏情况下,旋转延迟是转一圈的时间而不是半圈。看清楚题目问的是什么。
5.4 常见变体与应对策略
磁盘计算题的变体很多,但万变不离其宗。常见的变体包括:
变体一:给出磁盘容量和部分参数,求另一个参数。比如给出总容量、盘面数、每面磁道数、扇区大小,求每道扇区数。用总容量公式反推即可。
变体二:给出数据传输率和转速,求每道扇区数。数据传输率 = 每道扇区数 × 扇区大小 × 每秒转数。反推每道扇区数。
变体三:给出逻辑块号,求CHS地址。用上面的映射模板。
变体四:给出CHS地址,求逻辑块号。反向计算:逻辑块号 = 柱面号 × 每柱面扇区数 + 磁头号 × 每道扇区数 + 扇区号。
变体五:结合DMA,问传送一个扇区需要多长时间。把存取时间算出来,再加上DMA传送本身的时间(通常可以忽略,因为DMA传送和磁盘读出是重叠的)。
6. DMA与磁盘计算在真题中的配合方式
6.1 数据通路的完整描述
22年44题把DMA和磁盘计算放在一起,考的是"数据从磁盘到主存"的完整通路。这条通路可以拆成几段:
第一段:磁盘控制器从磁盘上读出数据。这涉及到磁头定位、扇区识别、数据读出。这一段的时间由磁盘的机械特性和旋转速度决定。
第二段:磁盘控制器把数据送到DMAC。这一段是硬件之间的数据传递,速度很快。
第三段:DMAC把数据写入主存。这涉及到总线请求、总线响应、地址驱动、数据写入。这一段的时间由总线速度和主存速度决定。
题目如果问"整个过程中CPU做了什么",答案就是:CPU在预处理阶段初始化了DMAC和磁盘控制器,在传送过程中没有参与数据搬运,在后处理阶段响应了DMAC的中断请求。
6.2 中断与DMA的配合
DMA传送结束后,DMAC通过中断通知CPU。这个中断和普通的I/O中断有什么区别?
普通I/O中断是"设备准备好传一个数据了,CPU来传一下"。DMA中断是"一整块数据都传完了,CPU来处理一下收尾"。前者中断频率高,后者中断频率低。这就是DMA效率高的原因——它把多次中断合并成了一次。
在22年44题的场景里,如果传送一个扇区的数据,DMA中断只发生一次。如果传送多个扇区,也只在全部传送完成后发生一次中断(假设DMAC配置为块传送模式)。
6.3 总线占用与CPU执行的关系
DMA传送期间,CPU能不能执行程序?这个问题的答案取决于DMA的传送方式。
如果是停止CPU访存方式,CPU在DMA传送期间不能访问主存,但可以执行不需要访存的指令(比如寄存器运算)。不过实际上,大多数指令都需要访存,所以CPU基本上被暂停了。
如果是周期挪用方式,CPU和DMA交替使用总线,CPU的执行速度会变慢,但不会完全停止。
如果是交替访存方式,CPU和DMA各占一半总线周期,CPU的执行速度降到正常的一半左右。
408考试里常考的是周期挪用方式,因为这种方式下CPU的执行和DMA的传送是并行的,只是CPU访存被"偷"走了一些周期。
6.4 从题目到答案的完整推理链
把22年44题的解题过程完整梳理一遍:
第一步,读题,提取磁盘参数和逻辑块号。
第二步,计算CHS地址。用每柱面扇区数做除数,逐步求出柱面号、磁头号、扇区号。
第三步,分析DMA传送流程。写出预处理、总线请求与响应、数据传送、后处理四个阶段。
第四步,如果题目问时间,计算寻道时间、旋转延迟、数据传输时间,求和。
第五步,如果题目问CPU的参与程度,说明CPU只在预处理和后处理阶段参与,数据传送阶段不参与。
这个推理链适用于所有类似的题目。你把这五步练熟,考场上不管题目怎么变,都能按部就班地解出来。
7. 备考408这块内容时我踩过的坑
7.1 把DMA和中断混为一谈
我刚开始复习的时候,总觉得DMA和中断差不多,都是"设备通知CPU"。后来才搞清楚,中断是设备通知CPU来传数据,DMA是设备通知DMAC来传数据,CPU只是最后收个通知。这个区别在答题的时候特别重要,因为题目会问"DMA方式下CPU参与哪些工作",如果你把数据传送也算成CPU的工作,那就错了。
7.2 磁道扇区计算时忽略编号顺序
有一次做模拟题,题目给的编号顺序是"磁头→扇区→柱面",我没注意,按默认顺序算了,结果整道题全错。后来我养成了一个习惯:拿到题目先看编号规则,没有明确规则就用默认的,有明确规则就严格按规则来。
7.3 存取时间计算时漏掉数据传输时间
有些题目给的数据量很小,数据传输时间确实可以忽略。但有些题目给的数据量很大,或者数据传输率很低,这时候数据传输时间就不能忽略了。我吃过一次亏,题目问"读取100个扇区需要多长时间",我只算了寻道和旋转延迟,忘了把100个扇区的数据传输时间加上去。
7.4 总线请求和响应写得不完整
DMA流程里,总线请求(HRQ)和总线响应(HLDA)是两个关键信号。我一开始答题的时候只写"DMAC获得总线控制权",没写这两个信号的名字和交互过程,结果被扣了分。后来我记住了:只要题目问DMA的工作过程,就把HRQ和HLDA写上去,这是得分点。
7.5 忽略DMA传送方向
DMA传送可以是读(从主存到设备)也可以是写(从设备到主存)。22年44题是从磁盘读到主存,所以是写主存。如果题目换成从主存写到磁盘,那DMAC的操作就反过来了。我有一回没注意方向,把地址寄存器的变化方向搞反了,虽然最后答案对了,但过程写错了。
8. 把这块知识真正用起来
8.1 用生活场景理解DMA
如果你觉得DMA的概念太抽象,可以这样理解:你是一个公司的老板(CPU),需要把一批货物从仓库(磁盘)搬到办公室(主存)。程序查询方式是你自己一趟趟搬;中断方式是你每搬一箱就接一个电话确认;DMA方式是你雇了一个搬运工(DMAC),告诉他仓库位置和办公室位置,他自己搬,搬完了告诉你一声。你在这期间可以做别的事,比如开会、签文件。
这个类比能帮你记住DMA的核心特征:CPU不参与数据搬运,只负责初始化和收尾。
8.2 用计算模板应对磁盘题
磁盘计算题的模板我已经在上面给了。你可以在纸上画一个表格,把每次计算的中间结果填进去,这样不容易出错。特别是逻辑块号到CHS的映射,一步步算,不要跳步。
8.3 用真题检验掌握程度
22年44题和24年45题都是很好的检验题。做完之后,不要只看答案对不对,要看过程完不完整。特别是DMA流程的描述,对照我上面给的四个阶段,看看自己漏了哪个。
8.4 把知识点串成线
组成原理的I/O章节不是孤立的。DMA和中断、程序查询是并列的三种方式,磁盘计算又和存储系统、总线结构有关。你在复习的时候,可以把这些知识点画成一张图:数据从磁盘出来,经过总线,通过DMA进入主存,CPU在两端做控制。这张图能帮你把零散的知识点串起来。
8.5 考场上的时间分配
408的I/O章节通常出2-3道题,分值不低。我的建议是:选择题快速过,把时间留给大题。DMA和磁盘计算的大题,读题要仔细,计算要一步步来,答题要写完整。特别是DMA流程的描述,宁可多写几句,不要漏掉关键步骤。
最后分享一个我自己的小技巧:每次做DMA相关的题目,我都在草稿纸上先画一条时间轴,标出预处理、传送、后处理三个阶段,然后把题目问的内容对应到时间轴上。这样不容易漏掉阶段,也不容易把不同阶段的工作搞混。磁盘计算题则是在草稿纸上画一个表格,把柱面号、磁头号、扇区号三列列出来,一步步填。这两个方法看起来笨,但考场上很管用。