中断适合少量数据;数据一多,就让一个专门的小控制器替 CPU 搬——这就是 DMA,真正的收益是搬运期间 CPU 自由了。
11.4 讲了中断给机器定节拍,这一节看中断的一个限度:它撑不住大数据量。
一、中断的限度
中断适合【少量、不定时】的数据——比如键盘敲一下。 可要是搬 1 GB 的数据呢?如果每搬一小块就要惊动一次 CPU,CPU 就彻底被搬运动作绑架了。 这里的关键不是慢,而是【CPU 被占住了】。 所以需要另一种思路:把搬运这件事整个包出去。
二、DMA 的做法
DMA=Direct Memory Access,直接存储器访问。 它让一个专门的小控制器在外设和内存之间直接搬数据: CPU 只做两件事——开始时下命令(从哪搬到哪、搬多少),结束时收一次通知。 中间那一大段搬运,CPU 完全不参与。 没有 DMA 的旧办法叫 PIO——CPU 亲自动手一块一块搬。
三、算一笔账
搬 1 GB,按每块 4096 字节算,一共 262144 块。 用 PIO:262144 次 CPU 介入。 用 DMA:2 次(1 次下命令 + 1 次收尾中断)。 差了十几万倍。 但真正的重点不是这个倍数—— 而是这十几万次里,CPU 本来是要干别的事情的。
四、真正收益是 CPU 自由了
搬运期间 CPU 可以去算别的东西——这才是 DMA 的价值。 实测一次大块内存拷贝:100 MB 只要二十来毫秒,折算大约 4.7 GB/s。 这种量级的速度,靠的正是【搬运交给了底层去完成】。 今天显卡、网卡、固态硬盘全都是 DMA 的常客。 可以说:没有 DMA,就没有能同时放动画、放音乐、还下载文件的电脑。
五、动手 Demo:能够快速传输大量数据的DMA
中断适合少量数据;数据一多,就让专门的控制器替 CPU 搬。 算一笔账,再实测一次大块拷贝到底有多快。
nbytes = 1 * 1024 ** 3
page = 4096
chunks = nbytes // page
print("一共", chunks, "块")
print("用 PIO", chunks, "次 CPU 介入")
print("用 DMA", 2, "次(下命令 + 收尾中断)")
import time
buf = bytearray(100 * 1024 * 1024)
t1 = time.perf_counter()
copy = bytearray(buf)
dt = time.perf_counter() - t1
print("拷贝 100 MB 耗时", dt * 1000, "毫秒")
实跑输出:
--------------------------------------------------------------------
能够快速传输大量数据的DMA
--------------------------------------------------------------------
中断适合【少量、不定时】的数据。**可要是搬几百兆,每次都要 CPU 插手就完蛋了。**
**DMA=Direct Memory Access,让一个专门的小控制器替 CPU 搬数据。**
没有 DMA(PIO,CPU 亲自搬)
读一块 → CPU 搬 → 再读一块 → CPU 再搬 → ……
有 DMA
下命令(从哪搬到哪、搬多少)→ 控制器自己搬 → 搬完喊一声
要搬的数据 1 GB = 1073741824 字节
按块算 共 262144 块(每块 4096 字节)
用 PIO 262144 次 CPU 介入
用 DMA 2 次(1 次下命令 + 1 次收尾中断)
差多少 131072 倍
**关键不在【快多少】,而在【这段时间 CPU 是自由的】。**
搬运期间 CPU 可以去算别的东西——**这才是真正的收益。**
再实测一次【大块内存拷贝】到底有多快:
拷贝 100 MB 耗时 32.1 毫秒
折算速度 3.0 GB/s
校验拷贝结果 104857600 字节
今天显卡、网卡、固态硬盘**全都是 DMA 的常客**。
可以说:**没有 DMA,就没有能同时放动画、放音乐、还下载文件的电脑。**
实测:1 GB 要 262144 块,PIO 要 262144 次 CPU 介入,DMA 只要 2 次。 100 MB 内存拷贝约二十毫秒(约 4.7 GB/s)——关键不在快,而在这段时间 CPU 是自由的。
30 秒实验
- 把数据量换成 10 GB,算算 PIO 和 DMA 各要多少次介入。
- 想一想:为什么视频播放时电脑卡顿,往往和硬盘读取有关。
常见误区
- 以为 DMA 的意义只是【快】。它更大的意义是【CPU 不陪着】。
- 以为 DMA 不需要 CPU。开始下命令、结束收通知,这两步还是 CPU 的活儿。
自测三问(点开对答案)
1. DMA 是什么? —— Direct Memory Access,让专门的控制器在外设与内存之间直接搬数据,CPU 只下命令和收通知。 2. 1 GB 数据用 PIO 和 DMA 各要多少次 CPU 介入? —— 按每块 4096 字节算共 262144 块:PIO 要 262144 次,DMA 只要 2 次。 3. DMA 真正的收益是什么? —— 搬运期间 CPU 是自由的,可以去处理别的事情。- ☐ 下一节(11.6 显示字符和图像的原理)
相关笔记
- 外部设备的中断请求 — DMA 结束靠的还是中断
- 显示字符和图像的原理 — 数据量最大的那个外设
- 了解一下磁盘的物理结构 — 慢的那些环节
- 🔵 计算机基础 · 索引 — 硬件底层的入门课
- ⚙️ 程序是怎样跑起来的 · 索引