DMA概述:什么是DMA、DMA在计算机体系结构中的位置、DMA vs CPU搬运数据
大家好,我是你们的芯片架构设计讲师。今天咱们聊聊DMA——这个在硬件系统里默默搬砖、却极其关键的模块。
先问大家一个问题:你写程序的时候,有没有遇到过CPU忙得团团转,结果大部分时间都在等数据?比如从外设读个数据,或者把内存里的数据搬到另一个地方。嗯,这就是典型的“CPU被数据搬运拖累”的场景。DMA就是来解决这个问题的。
什么是DMA?
DMA,全称Direct Memory Access,直接存储器访问。说白了,就是让硬件自己搬数据,不用CPU插手。
我习惯这么理解:CPU是公司的CEO,负责做决策、跑算法。DMA就是个专职的搬运工。CEO说“把仓库A的货搬到仓库B”,然后搬运工自己干,CEO继续开会。等搬完了,搬运工说一声“老板,搬完了”。
这个“说一声”就是中断。CPU收到中断,知道数据已经到位,直接拿来用就行。
核心要点:DMA的本质是硬件化的数据搬运引擎。它解放了CPU,让CPU专注于计算和控制。
我在项目中遇到过不少刚入行的工程师,总觉得DMA可有可无。直到有一次,一个视频处理项目,CPU要同时处理图像算法和搬运帧数据,结果帧率死活上不去。加了DMA之后,CPU负载从95%降到了30%,帧率直接翻倍。嗯,从那以后,没人再质疑DMA的价值了。
DMA在计算机体系结构中的位置
DMA不是独立存在的,它需要和系统总线、内存、外设配合工作。咱们来看一张图,我画了个简化的系统结构。
你看这张图,DMA控制器和CPU、内存、外设都挂在系统总线上。这意味着DMA可以直接访问内存和外设,不需要经过CPU中转。
实际项目中,DMA的位置会有些变化。有的芯片把DMA放在CPU内部,叫“内置DMA”;有的做成独立模块,挂在总线上。我个人习惯用独立DMA,灵活性更高,带宽也更容易保证。
DMA vs CPU搬运数据
咱们来做个对比。假设要从外设搬1MB数据到内存。
| 对比项 | CPU搬运 | DMA搬运 |
|---|---|---|
| 执行方式 | CPU逐字节/逐字读取→写入 | 硬件自动完成,无需软件干预 |
| CPU占用 | 100%占用,无法做其他事 | 仅初始化时占用,搬运时CPU可做其他任务 |
| 搬运速度 | 受限于CPU指令执行速度 | 硬件流水线,通常快3-10倍 |
| 功耗 | CPU全速运行,功耗高 | 专用硬件,功耗低 |
| 灵活性 | 可做任意数据处理(如校验、转换) | 通常只做纯搬运,部分支持简单运算 |
| 适用场景 | 小数据量、需要处理的数据 | 大数据量、周期性搬运、实时性要求高 |
你想想看,CPU搬运数据就像让CEO亲自搬箱子。CEO搬一个箱子要5秒,而且搬的时候不能开会、不能签文件。DMA搬箱子只要1秒,CEO可以同时处理10个会议。
为什么会这样?因为CPU的指令执行是串行的——取指令、译码、执行、写回,每一步都要走一遍。而DMA是纯硬件状态机,一旦配置好,就按固定流程跑,没有指令开销。
实战小贴士:我建议在小数据量(比如几十字节)的场景下,用CPU搬运反而更快。因为DMA的初始化开销(配置寄存器、启动、等待完成)可能比直接CPU搬运还大。这个阈值一般在几百字节到几KB,具体要看芯片的DMA延迟。
来看一段伪代码,对比两种方式:
// CPU搬运方式
void cpu_copy_data(uint32_t *src, uint32_t *dst, int len) {
for (int i = 0; i < len; i++) {
dst[i] = src[i]; // CPU逐字搬运,期间不能做其他事
}
}
// DMA搬运方式
void dma_copy_data(uint32_t *src, uint32_t *dst, int len) {
// 1. 配置DMA源地址、目的地址、长度
DMA->SRC_ADDR = (uint32_t)src;
DMA->DST_ADDR = (uint32_t)dst;
DMA->LENGTH = len;
// 2. 启动DMA
DMA->CTRL |= DMA_START;
// 3. CPU可以去做其他任务,比如处理另一个数据流
process_other_data();
// 4. 等待DMA完成中断(或者轮询标志位)
while (!(DMA->STATUS & DMA_DONE));
}
看到区别了吗?CPU搬运时,整个函数都在做搬运,CPU被绑死了。DMA方式下,CPU只需要配置几个寄存器,然后就可以去干别的。等DMA搬完了,CPU回来收个尾就行。
注意:DMA搬运期间,CPU和DMA可能会竞争总线带宽。如果系统总线带宽不够,DMA会抢走CPU访问内存的带宽,导致CPU变慢。我曾经在一个项目中,DMA把总线占满了,CPU连中断都响应不了。后来加了总线仲裁和优先级控制才解决。
最后总结一下DMA的核心价值:
- 解放CPU:让CPU从繁琐的数据搬运中解脱出来
- 提升吞吐量:硬件搬运速度远快于软件
- 降低功耗:专用硬件比通用CPU更节能
- 保证实时性:DMA的响应时间可预测,适合音视频等实时场景
嗯,DMA的基本概念就讲到这里。记住一句话:能用DMA搬的数据,就别让CPU动手。这是硬件设计里性价比最高的优化手段之一。
公众号:蓝海资料掘金营,微信deep3321