首页/计算机组成原理/I/O系统/DMA方式 🔗 在 Obsidian 中打开
计算机组成原理 · I/O系统

DMA方式

难度 ★★★重要度 ★★★★★ 考查频率 低题型 选择 / 综合 直接存储器访问数据块传输周期窃取通道
速查
DMA 让 DMAC 直接在 I/O 设备与主存间成组传输数据,不经过 CPU;CPU 只在开始(初始化)与结束(收尾中断)参与。三种总线使用方式:停止CPU访存周期窃取交替访问

概述

DMA(Direct Memory Access,直接存储器访问)是一种高速 I/O 方式。DMA 控制器直接控制数据在 I/O 设备和内存之间传输,无需 CPU 逐字节干预。CPU 只在传输开始和结束时参与,数据传输期间可以做其他工作。

适用场景适合高速设备(磁盘、网卡、显卡等)——成块数据、CPU 干预少。

基本原理

与中断方式的区别

方式数据通路CPU 干预粒度适用设备
中断方式I/O → CPU 寄存器 → 内存每传一个字/字节都需 CPU 介入中低速
DMA 方式I/O ↔ 内存(不经 CPU)整个数据块只干预一次(开始+结束)高速

工作流程

1. CPU 向 DMA 控制器发送命令:
   - 内存起始地址、传输数据长度、传输方向(读/写)、设备号
2. CPU 继续执行其他程序(DMA 接手总线)
3. DMA 控制器控制数据传输:
   - 每次传输一个字/字节,发总线请求占用总线
   - 数据直接在 I/O 设备与内存间传送
   - 地址寄存器 +1,计数器 -1
4. 传输完成 → DMA 向 CPU 发中断请求
5. CPU 响应中断,处理传输结束

DMA 控制器组成

主要寄存器

DMA 控制器
  MAR(内存地址寄存器) ← 当前内存地址
  DAR(设备地址寄存器) ← 设备端口地址
  WC (字计数器)       ← 剩余传输字数(补码)
  CR (控制/状态寄存器) ← 传输方向、模式等
  BR (总线请求)       → 向仲裁器发请求
  BG (总线授权)       ← 接收仲裁器授权
  IRQ(中断请求)       → 传输完成后中断 CPU
  数据缓冲寄存器         ← 暂存传输数据

各寄存器功能

寄存器功能初始值来源
MAR当前内存地址CPU 设置
WC剩余字数CPU 设置(补码)
CR控制信号CPU 设置
DAR设备地址CPU 设置

DMA 的传送方式

停止 CPU 访问(Stop CPU)

DMA 传输期间,CPU 完全放弃总线控制权,直到传输结束才归还。

CPU: ────────|停止访问|────────────
DMA:         |=========传输========|
特点控制简单、传输速度快;但 CPU 长时间停止,浪费严重。适用数据块大且速率极高的场景。

周期窃取(Cycle Stealing)⭐

DMA 每次只窃取一个总线周期传输一个字,然后归还总线给 CPU。

CPU: ──工作──|窃取|──工作──|窃取|──工作──
DMA:         |传输|        |传输|
特点CPU 只暂停一个周期,影响最小;有总线切换开销,效率略低。是大多数 DMA 应用采用的方式。

DMA 与 CPU 交替访问

DMA 和 CPU 各自使用总线的不同部分,或在时钟的不同相位访问,无需总线仲裁,效率最高,但需要特殊硬件支持。

DMA 的传送过程

读操作(内存 → 设备)

1. DMA 发总线请求 BR        6. MAR ← MAR + 1
2. 仲裁器发总线授权 BG      7. WC  ← WC - 1
3. DMA 将 MAR 地址送地址总线 8. 归还总线(BG 撤销)
4. DMA 发读命令(内存→数据总线)9. 若 WC ≠ 0,回到步骤 1
5. 数据从数据总线送到设备    10. 若 WC = 0,发中断请求

写操作(设备 → 内存)

1. DMA 发 BR                6. MAR ← MAR + 1
2. 仲裁器发 BG              7. WC  ← WC - 1
3. DMA 将 MAR 地址送地址总线 8. 归还总线
4. 设备数据送到数据总线      9. 若 WC ≠ 0,回到步骤 1
5. DMA 发写命令(数据总线→内存)10. 若 WC = 0,发中断请求

CPU 初始化 DMAC

void setup_dma(int *buffer, int length, int dir) {
    out(DMA_MAR, buffer);            // 内存起始地址
    out(DMA_WC, -length);            // 字计数(补码)
    out(DMA_CR, dir | DMA_ENABLE);   // 控制命令
    // 启动后 CPU 可以做其他事
}

DMA 与 CPU 的总线竞争

DMA 和 CPU 共享系统总线,需要总线仲裁机制。通常 DMA 优先级高于 CPU(保证数据不丢失),但可通过编程调整。

CPU 性能损失 = DMA 占用的总线周期 / 总周期数
例:CPU 主频 1GHz,总线周期 100MHz
    DMA 传输速率 100MB/s,总线宽度 32 位
    DMA 占用率 = 100MB/s / (100MHz × 4B) = 25%
    CPU 性能损失约 25%

DMA 方式的优缺点

优点

  • CPU 利用率高:数据传输期间 CPU 可做其他工作
  • 传输速度快:直接访问内存,无需 CPU 中转
  • 适合高速设备(磁盘、网卡、显卡)
  • 数据块传输:一次设定,传输整个块

缺点

  • 硬件复杂:需要专用 DMA 控制器
  • 总线竞争:DMA 和 CPU 争用总线
  • 初始化开销:每次传输需 CPU 设置参数
  • 不适合少量数据(初始化开销大于收益)

DMA 的高级特性

链式 DMA(Scatter-Gather)

支持不连续内存块的传输,DMA 描述符链表:
[地址1, 长度1] → [地址2, 长度2] → [地址3, 长度3] → NULL
DMA 控制器自动按链表传输,无需 CPU 干预

多通道 DMA

多个 DMA 通道独立工作,每个通道连接不同设备
通道间可并行传输

DMA 与其他 I/O 方式对比

特性程序查询程序中断DMA通道
CPU 干预每字节每字节开始和结束开始
传输单位字节字节数据块数据块
CPU 利用率最高
硬件复杂度最高
适用速度最高
灵活性最高

通道方式(简介)

通道是专用的 I/O 处理器,有自己的指令集(通道指令),可独立执行 I/O 程序。CPU 只需启动通道,通道自动完成全部 I/O,利用率最高。

类型传输单位复杂度并发性
字节多路通道字节多个低速设备并行
数组多路通道数据块多个高速设备交替
选择通道数据块一次只服务一个设备

DMA 传输的计算

传输时间   = 数据量 / DMA 传输速率
例:传输 1MB 数据,DMA 速率 100MB/s → 10ms

CPU 占用   = 初始化时间 + 中断处理时间
            (DMA 传输期间 CPU 可做其他工作)

总线带宽占用:
CPU 可用带宽 = 总线带宽 - DMA 带宽占用
例:总线带宽 400MB/s,DMA 占用 100MB/s → CPU 可用 300MB/s

易错点

必记
  1. DMA 传输期间 CPU 可以做其他工作,不是停止。
  2. 周期窃取每次只偷一个总线周期,不是整个传输期间。
  3. DMA 的 WC 用补码表示,每次加 1,到 0 时表示传输完成。
  4. DMA 传输完成后向 CPU 发中断,CPU 做收尾处理。
  5. DMA 初始化需要 CPU 完成(设置地址、长度、方向)。
  6. DMA 和 CPU 争用总线,通常 DMA 优先
  7. DMA 不适合传输少量数据(初始化开销大于收益)。

记忆卡片

DMA 数据经过 CPU 吗?
不经过,I/O 与内存间直接传输。
三种总线使用方式?
停止 CPU 访存 / 周期窃取 / 交替访问。
周期窃取每次偷多久?
一个总线周期(传一个字)。
WC 何时表示完成?
补码计数,加 1 到 0 时完成。
DMA 适合什么设备?
高速设备(磁盘、网卡),成块传输。
CPU 何时参与 DMA?
仅初始化(开始)与收尾中断(结束)。

交互动画 · DMA 三种总线使用方式

总线占用(每段 = 一个总线周期) CPU 周期 周期 周期 周期 周期 周期 周期 周期 DMA 传输 传输 传输 传输 传输 传输 传输 传输 点击上方按钮查看三种方式下 CPU 与 DMA 对总线的占用
选择一种总线使用方式
点击上方按钮开始
绿色块 = CPU 占用总线,橙色块 = DMA 占用总线(点亮部分表示实际占用);黑色文字段表示空闲/被对方占用。

相关知识点

program-interrupt-mode programmed-io io-interface dma-controller-detail

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。