Skip to content

DMA直接存储器访问

2026 大纲 六(三)3 DMA 方式(DMA 控制器的组成、DMA 传送过程)。前一档方式为什么撑不住见《程序查询与程序中断方式》,总线控制权由谁裁决见《总线概述》。

中断要的是 CPU 的时间,DMA 要的是总线

中断方式的病根,常被说成"打断得太频繁"。但频繁只是症状——真正的问题是数据凭什么非要经过 CPU 不可。查询与中断方式下,数据走的是三段通路:

设备接口CPU 寄存器主存

CPU 在通路的正中间,是不可替代的搬运工,所以每个数据都得惊动它一次。DMA 做的事只有一件:把这条通路短路成「设备接口 ↔ 主存」,让 CPU 从通路上下来。 控制器自己发主存地址、自己发读写信号,数据不进 CPU。

由此推出一句能派生出后面一切结论的话:中断请求的是 CPU 的执行权,DMA 请求的是总线控制权。 两句话里的名词一换,三处差别就跟着定了:

  • 由谁裁决:执行权归 CPU 分配,走中断判优;总线控制权归总线仲裁器分配,走总线仲裁。DMA 请求根本不进中断优先级体系。
  • 什么时候能切:中断要交出执行权,必须等一条指令执行结束——指令做到一半时中间结果散落在各暂存器里,PC 与 PSW 不干净、恢复不了;DMA 只占总线,而总线的最小不可分割单位是一个存储周期,在存储周期边界就能切。粒度取决于让出的那样东西的最小完整单位,这两个边界不用背。
  • 争起来谁让谁:CPU 与 DMA 同时要访问主存时,DMA 优先。判据不是"谁更重要",而是谁耽误不起——外设的数据不及时取走就会被下一个覆盖(磁盘转过去要等整整一圈),而 CPU 延后一两个存储周期只是慢一点点。

这条"总线控制权"的主线会一直贯到本篇最后一节:三种 DMA 传送方式(停止 CPU 访存、周期挪用、交替访存)之间的全部差别,也不过是总线控制权在 CPU 与 DMAC 之间怎么切分

交互可视化

加载可视化中...

一、DMA 要拆掉的是哪一堵墙

中断方式已经把外设准备数据的时间还给了 CPU,但留下一段压不掉的开销:每传一个数据,CPU 都要走一遍"响应 + 保护现场 + 搬数据 + 恢复现场 + 返回"。对高速设备,数据传输率越高中断越频,越过 T准备<T中断 那条线就不是慢,是丢数据

DMA 改的是更根本的一条——数据凭什么要经过 CPU:

设备接口DMA 控制器控制总线主存

二、核心辨析:DMA 请求的是总线控制权

中断请求的是处理器的执行权,DMA 请求的是总线的控制权

  • 中断:设备请求 CPU 执行一段程序(ISR)。CPU 让出的是自己的执行时间。
  • DMA:控制器请求接管总线,自己去发地址、发读写信号、走数据线。CPU 让出的是总线,程序照跑。
程序中断方式DMA 方式
请求的对象CPU 的执行权总线控制权
谁来裁决中断判优电路总线仲裁机制
响应时刻一条指令执行结束后一个存储周期(总线事务)结束后
CPU 让出什么一段执行时间一段总线占用时间
数据经过 CPU
传送单位字 / 字节数据块
中断请求在其中的作用请求传送数据报告整块传送完成

三、DMA 控制器的组成

要让控制器脱离 CPU 自己完成一次块传送,它至少得知道四件事:往哪写、还剩多少、数据暂存在哪、这次是读还是写——四个寄存器由此一一对应:

寄存器装什么由哪个前提逼出来
AR 主存地址寄存器当前要访问的主存地址它要自己发地址上总线;每传一个数据自动增量
WC 字计数器还剩多少个数据没传它要自己判断何时结束;减到 0 即终点,同时触发结束中断
DR 数据缓冲寄存器正在过渡的那个数据设备侧与主存侧的时序和位宽都不同,需要一拍缓冲
CR 命令状态寄存器本次传送的方向与状态它要知道这次是读还是写

另有中断请求电路与控制·时序逻辑;有的 DMAC 还设设备地址寄存器,指明本次传送对应哪台设备。

两处口径要跟着钉住。其一,AR 的增量等于 DR 的字节数——"每传一个字"里的字有多宽,由 DR 的位宽决定(常见 8/16/32/64 位,题面一定会给),算总线请求次数用的也是它,不要默认按 1 字节其二,DR 不改变数据通路的两端:它只是过渡缓冲,通路仍然是"设备接口 ↔ 主存",说成"数据通路在设备接口和 DMA 控制器之间"是错的。

   ┌─────────┐                                  ┌─────────┐
   │   CPU   │                                  │  主存    │
   └────┬────┘                                  └────┬────┘
        │                                            │
   ═════╪══════════════ 系统总线 ═══════════════════╪═════
        │                     │                      │
        │  ①设参数/③完成中断   │ ②数据直接在这两者之间走 │
        │                ┌────┴─────┐                │
        └───────────────→│ DMA 控制器 │←──────────────┘
                         │ AR WC DR CR│
                         └────┬─────┘
                              │  设备数据
                         ┌────┴─────┐
                         │   外设    │
                         └──────────┘

CPU 只在 ① 和 ③ 出现,② 整段它完全不在场。

四、DMA 传送过程

预处理(CPU 参与):申请并初始化缓冲区(输出则先把数据备好)→ 主存首址进 AR、传送个数进 WC、传送方向进 CR、设备地址进设备地址寄存器 → 发"启动 DMA 传送"命令,然后调度 CPU 去执行其他进程

数据传送(CPU 不参与):DMAC 接管总线逐个搬运。每传一个:设备把数据送入 DR(或取走)→ DMAC 把 AR 送地址总线、在读/写线上发命令 → 数据经数据总线在 DR 与主存之间传送 → ARAR+DR 的字节数WCWC1 → 若 WC0 回到第一步。整段不需要 CPU 执行任何指令

后处理(CPU 参与)WC=0 时 DMAC 发"DMA 结束"中断,CPU 在 ISR 里校验数据、决定是否继续下一批、必要时重设参数。

三个阶段摆在一起,就能看出"DMA 全程不需要 CPU"这句话错在哪:只有中间那一段不需要。预处理要 CPU 逐个把参数写进 DMAC 的端口——而且这一步用的正是程序查询方式(写端口是同步的、瞬时完成的动作,不值得为它设中断);后处理要 CPU 在中断服务程序里善后。准确的说法是"DMA 传送过程不需要 CPU 干预",少了"传送过程"四个字就成了错句。

同理,DMA 没有取代中断:开头靠 CPU 主动设参数,结尾靠中断通知完成。它做的是把中断从"每传一个数据一次"降到"每传一块一次"。

五、三种数据传送方式及其适用条件

DMAC 与 CPU 共享主存,两者都要访存就产生冲突。三种解法不是好坏排序,而是三套适用条件不同的方案

停止 CPU 访存:DMAC 发停止信号,CPU 交出地址线、数据线和有关控制线,直到整块传完才收回。控制最简单,代价是 CPU 整段基本不工作。

周期挪用(周期窃取):每当设备发出 DMA 请求就挪用一个(或几个)存储周期去访存,传完一个立即释放;设备不请求时 CPU 照常访存。这是一种单数据传送方式。请求到来时三种情形:CPU 此刻不需访存(如正执行耗时较长的运算指令)→ 不冲突;CPU 正在访存 → 等这个存取周期结束才让出;CPU 也正要访存 → 冲突,DMA 优先,CPU 延后一两个存取周期。

DMA 与 CPU 交替访存:把一个 CPU 工作周期分成两个分周期,一个专供 DMAC 访存、另一个专供 CPU。总线控制权由分周期信号直接切换,不需要申请、建立、归还;两者各有独立的访存地址寄存器、数据寄存器与读/写信号,总线实质变成受两个分周期控制的多路转换器。CPU 既不停止也不等待,代价是硬件逻辑复杂得多。

方式CPU 受影响控制复杂度成立条件
停止 CPU 访存大(整段停摆)高传输率设备的成组传送
周期挪用小(延后一两个存取周期)外设读写周期 > 主存周期
交替访存CPU 工作周期 > 主存存取周期

这三行不是好坏排序,而是一条因果链CPU 让出的时间越少,对时序配合的要求就越苛刻,硬件也越复杂。停止访存不需要任何时序配合,代价是 CPU 整段停摆;交替访存要求 CPU 的工作周期长到能塞下一个完整的主存存取周期,才可能"两人各用半拍谁也不耽误谁",代价是一整套双端口式的硬件。

周期挪用那一行的成立条件也值得追一句为什么。每挪用一次,DMAC 都要走申请 → 建立 → 归还总线控制权这三步——对主存只占 1 个存储周期,对 DMA 接口实质要占 2~5 个。所以外设两次读写之间的间隔必须比主存周期宽出不少,这三步才来得及走完,这正是"外设读写周期 > 主存周期"的由来。

同一块数据下三种方式各占 CPU 多久:把"停机停的是设备时间"落到数字上(想弄清那个 10 倍差距从哪来时展开)

设一块共 n 个数据、主存存取周期 Tm、设备两个数据之间的间隔(准备一个数据的时间)Td,且 TdTm(对绝大多数外设成立)。

方式CPU 被剥夺的时间怎么来的
停止 CPU 访存n×TdCPU 从块首停到块尾,设备准备数据的那些间隔也一并停着
周期挪用n×Tm只在每次实际访存时让出一个存取周期,间隔期间 CPU 照跑
交替访存0两个分周期互不重叠,CPU 一个周期也没少

关键是第一行不是 n×Tm:停机停的是"整块传送的全过程",而整块传送的时间由设备速度决定,不由主存决定。两者之比正好是

T停机T挪用TdTm

举个数:n=1024Tm=100 ns、Td=1 μs 时,停止 CPU 访存让 CPU 停摆约 1024 μs,周期挪用只占约 102.4 μs,相差 10 倍——正是 Td/Tm

也正因如此,停止 CPU 访存只在 Td 逼近 Tm(设备快到几乎不用等)时才划算——这与它的适用条件"数据传输率很高的设备做成组传送"是同一句话的两种说法。

它对主存也是浪费。 即使外设很快,两个数据之间的准备间隔仍远大于一个存取周期——CPU 停着不访存、外设又在准备下一个,主存这段时间是空闲的。工程上的补救是在 DMA 接口里加一个小容量存储器,设备先与它交换,再由它成批与主存交换,从而缩短占用总线的时间。

六、一次磁盘传送里,三种 I/O 方式是分工的

三种 I/O 方式常被当成互斥的三选一,但一次真实的磁盘读写里它们是配合使用的:

图 8.24 DMA 方式进行磁盘数据传送过程

图 8.24 DMA 方式进行磁盘数据传送过程

阶段用哪种方式为什么
设置传送参数(初始化 DMAC)程序查询CPU 主动写寄存器,同步完成,不值得中断
寻道中断磁头移动是毫秒级机械动作,CPU 不能干等
查找扇区中断同上
连续读写数据DMA数据率高、成批传送,逐个数据中断扛不住
传送结束、校验中断一次性事件,通知 CPU 做后处理
两道完整演算:CPU 占比与总线请求次数,以及单位换算的两个坑(想核对自己会不会踩坑时展开)

(一)DMA 的 CPU 占比,并与中断方式对照。 某机主频 1 GHz,某外设数据传输率 2 MB/s,接口数据缓冲寄存器 32 位。改用 DMA 后每次传送一块 4 KB,DMA 的预处理与后处理合计 200 条指令,CPI = 5。

① 把指令条数折成时钟周期(公式要的是周期数,题面给的是指令条数):

m=200 ×5=1000 时钟周期

② DMA 每秒被触发多少次(以为单位):

N=2×106 B/s4096 B/块488.28 次/秒

③ 占比(数据传送阶段完全由 DMAC 完成,不计入 CPU):

488.28×10001×1094.88×104=0.0488%

同一台设备在《程序查询与程序中断方式》里用中断方式算出的占比是 75%。差距只有一处来源:中断以 4 B 为单位触发,DMA 以 4096 B 为单位触发,频率相差 1024 倍。

(二)总线请求次数。 某 DMAC 的 DR 为 32 位,一次传送一个 2 KB 数据块,DR 每装满一次就发一次总线请求。先把两边统一到再除:

N=2048 B×832 =1638432=512 

这类计算最容易出错的两处:

  1. 传送单位不是"1 字节"。中断方式的单位由数据端口/缓冲寄存器位宽给出,DMA 方式的单位是块大小。单位取错,结果整体偏离若干倍。
  2. 字节和位不能混除。直接用 2048÷32 会得到 64,差 8 倍;若 DR 是 64 位则 16384÷64=256 次。另外指令条数必须乘 CPI 才是周期数,预处理与后处理的指令数要先相加再乘。

考点速记

  1. 中断请求的是 CPU 执行权,DMA 请求的是总线控制权——由此推出裁决机制(中断判优 vs 总线仲裁)与响应时刻(指令结束 vs 存储周期结束)的全部差别,粒度取决于让出的东西的最小完整单位。
  2. DMAC 四个寄存器 AR/WC/DR/CR 可从"要独立访存"一个前提推出;三阶段中只有数据传送不需要 CPU,预处理用查询方式、后处理靠中断——DMA 没有取代中断,只是把中断从每数据一次降到每块一次
  3. 三种传送方式不是好坏排序,条件依次是"高传输率成组传送 / 外设读写周期 > 主存周期 / CPU 工作周期 > 主存存取周期";CPU 让出的时间越少,时序要求越苛刻、硬件越复杂。停机方式停的是设备时间不是主存时间,故被剥夺时间之比为 Td/Tm

这一节在真题里被考过的形式

DMA 是 I/O 章出题最稳的一节——近年几乎年年一道选择题,另外三道大题的分问都落在这里

  • 问 DMA 的数据传输通路位于哪两者之间(2024-22)。答设备接口与主存之间。四个选项恰好把三段通路的各种错配摆齐:CPU 与主存之间是普通访存、CPU 与 DMAC 之间只走预处理时的参数、设备接口与 DMAC 之间只是那个过渡缓冲。这道题就是本篇开篇"把三段通路短路成两段"的直接复述,DR 的存在不改变通路的两端
  • 逐条判断 DMA 传送的四个环节(2019-22)。四句全对:传送前由设备驱动程序设参数(预处理)、传送前由 DMAC 请求总线使用权、传送由 DMAC 直接控制总线完成、结束后的处理由中断服务程序完成。这道题把三阶段分工完整走了一遍,也顺带否掉了"DMA 全程不需要 CPU"——首尾两段都要 CPU
  • 判断周期挪用方式下的四句叙述(2020-22)。错项是 "在整个数据块的传送过程中,CPU 不可以访问主存储器"——那是停止 CPU 访存方式的性质,周期挪用只在实际访存的那一两个存储周期里让出总线,其余时间 CPU 照常访存。另三句都对:接口的数据缓冲寄存器 32 位,故每凑满 32 位就发一次总线请求(周期挪用是单数据传送方式);CPU 与 DMAC 争主存时 DMA 优先;块传完会产生"DMA 传送结束"中断。⚠️ 三种传送方式的性质互相串用,是这一节最主要的错项来源。
  • 判断哪些设备适合 DMA(2025-21,与方式对比共享)。答网卡与固态硬盘——传输率高且成批传送。
  • 算 DMA 方式下的 CPU 占比(2009-43 第 2 问、2018-43 第 3 问)。公式与前两种方式共用骨架,唯一的区别是每秒介入次数从 R/u 变成 R/BsBs 是块大小)。2009-43:R=5 MB/s、Bs=5000 B,故每秒 1000 次;预处理加后处理 500 周期、主频 500 MHz,占比 =1000×500/(500×106)=0.1%。2018-43 第 3 问同型:40×106/1000=40000 次、每次 500 周期,占比 =4%。⚠️ 别把 Bs 写成 u——这一处写错,答案会差上千倍,而这正是 DMA 相对中断的全部增益所在(同题第 1 问中断方式算出来是 4%,第 3 问 DMA 也是 4%,是因为设备 B 快了 20 倍,恰好抵掉;口径本身没有变)。
  • 算一个扇区要发多少次总线请求,并判断 DMA 能否抢到总线(2022-44 第 3 问)。扇区 512 B、DMAC 数据缓冲区 64 位(8 B),故 512/8=64 次。第二问答可以,理由要写到时限上:磁盘数据不及时传送就会丢失(磁头转过去要等整整一圈),而 CPU 延后一两个存储周期只是慢一点——判据是"谁耽误不起",不是"谁更重要"。

复习优先级:这一节选择与大题都要拿满。选择题的错项集中在两处——三种传送方式的性质互相串用把"传送过程不需要 CPU"说成"全程不需要 CPU";计算题只有一个新口径(每秒次数用 R/Bs)和一个位宽陷阱(缓冲区位宽决定每次传几个字节)。

易错:说 DMA 的数据通路在设备接口和 DMA 控制器之间。两端是设备接口与主存,DR 只是过渡缓冲。

易错:把"DMA 传送过程不需要 CPU"说成"DMA 全程不需要 CPU"。预处理与后处理都要 CPU。

易错:把停止 CPU 访存的性质套到周期挪用上。周期挪用期间 CPU 仍可访存。

易错:算 DMA 占比时把每秒次数写成 R/u。DMA 是按块介入,分母是块大小 Bs

易错:算总线请求次数时按 1 字节。用 DMAC 数据缓冲寄存器的位宽换算。

教材出处
  • "中断 I/O 方式请求的是处理器的时间,而 DMA 方式下请求的是总线控制权";一次磁盘传送中查询、中断、DMA 的分工(图 8.24):袁春风《计算机组成与系统结构》第 3 版 §8.4.3,印刷页 p301
  • 3 种 DMA 方式(CPU 停止法、周期挪用法、交替分时访问法)与 DMA 操作三步骤、DMAC 中的寄存器构成:同书 §8.4.3,印刷页 p302
  • 三种传送方式的适用条件——停止 CPU 访存适用于数据传输率很高的设备成组传送;周期挪用实质占用 2~5 个主存周期,比较适合外设读 / 写周期大于主存周期的情况;交替访问适合 CPU 工作周期比主存存取周期长的情况:唐朔飞《计算机组成原理》第 3 版 §5.6,印刷页 p201~p203(图 5.46 DMA 的三种传送方式)

相关知识

程序查询与程序中断方式三种 I/O 方式对比总线概述I/O 接口

真题练习