1. DMA基础概念:DMA工作原理、DMA与CPU数据搬运的区别、DMA在Linux系统中的角色
1.1 DMA工作原理
DMA(Direct Memory Access,直接存储器访问)是一种允许硬件子系统直接读写系统内存的机制,无需CPU参与数据传输的每个字节。DMA控制器作为独立的总线主设备,在CPU初始化传输参数后,自动完成数据从源地址到目的地址的搬运。
核心思想:将CPU从繁重的数据拷贝任务中解放出来,使其专注于计算与控制逻辑。
1.2 DMA与CPU数据搬运的核心区别
CPU搬运数据(PIO模式)与DMA搬运在性能、资源占用和适用场景上存在本质差异。下表从多个维度进行对比:
| 对比维度 | CPU搬运(PIO) | DMA搬运 |
|---|---|---|
| 执行主体 | CPU核心逐字节/逐字搬运 | DMA控制器独立完成 |
| CPU占用率 | 100%(传输期间无法执行其他任务) | 仅初始化(~1%)+ 中断处理(~2%) |
| 吞吐量 | 受限于CPU频率和指令发射宽度 | 可达总线带宽上限(如PCIe Gen4 x16: ~32 GB/s) |
| 延迟 | 低(无额外仲裁开销) | 略高(需总线仲裁和DMA引擎启动) |
| 适用场景 | 小数据量(< 64字节)、控制寄存器访问 | 大数据块(≥ 512字节)、流式I/O |
| Cache一致性 | 天然一致(CPU直接访问) | 需软件维护或硬件一致性协议 |
性能权衡:对于小于64字节的传输,PIO模式因省去DMA引擎启动开销反而更快;超过512字节后DMA优势显著。嵌入式系统中常以阈值(如256字节)动态切换两种模式。
1.3 DMA在Linux系统中的角色
Linux内核将DMA抽象为多个子系统协同工作的框架,涵盖API层、驱动层、硬件抽象层和内存管理。其核心角色包括:
- 数据通路加速器:为块设备(NVMe/SATA)、网络(NIC)、多媒体(GPU/VPU)提供零拷贝数据路径。
- 内存管理协同者:通过DMA API(
dma_alloc_coherent、dma_map_single)管理一致性/流式映射。 - 硬件抽象层:提供统一接口屏蔽不同SoC的DMA控制器差异(如Intel IOMMU、ARM SMMU)。
- 性能监控者:通过
/sys/kernel/debug/dma-api/和perf事件暴露DMA使用统计。
1.4 Linux DMA API关键函数
内核为驱动开发者提供两组核心DMA API,分别对应一致性映射和流式映射:
| API函数 | 用途 | 映射类型 |
|---|---|---|
dma_alloc_coherent() |
分配一致性内存(Cache与DMA视图一致) | 一致性映射 |
dma_free_coherent() |
释放一致性内存 | 一致性映射 |
dma_map_single() |
映射单个缓冲区用于DMA传输 | 流式映射 |
dma_unmap_single() |
解除流式映射 | 流式映射 |
dma_map_sg() |
映射分散/聚集列表 | 流式映射 |
dma_unmap_sg() |
解除分散/聚集映射 | 流式映射 |
dma_sync_single_for_cpu() |
将DMA缓冲区同步到CPU视图 | 流式同步 |
dma_sync_single_for_device() |
将CPU修改同步到DMA设备视图 | 流式同步 |
常见陷阱:流式映射后CPU不能直接访问缓冲区,除非先调用
dma_sync_single_for_cpu()。一致性映射虽然方便,但会禁用Cache优化,适合小缓冲区或控制结构,不适合大数据块。
1.5 DMA传输模式分类
根据传输方向和参与方,DMA操作可分为以下三种基本模式:
- 内存→外设(DMA写):从内存读取数据写入外设FIFO,典型场景:网卡发送数据、GPU上传纹理。
- 外设→内存(DMA读):从外设FIFO读取数据写入内存,典型场景:磁盘读取、网卡接收、摄像头采集。
- 内存→内存(Memcpy DMA):两个内存区域之间的拷贝,由DMA引擎完成,典型场景:数据重排、加密加速、零拷贝转发。
1.6 性能关键指标
在后续章节的测试工具中,我们将重点测量以下DMA性能指标:
| 指标 | 定义 | 典型值(PCIe Gen4 x4) |
|---|---|---|
| 带宽 | 单位时间内传输的数据量(MB/s或GB/s) | ~7.0 GB/s(单向) |
| 延迟 | 从DMA请求发出到传输完成的时间(ns) | ~500 ns(小包) |
| 传输效率 | 有效数据带宽 / 总线带宽 × 100% | 85%~95% |
| CPU卸载率 | DMA节省的CPU周期 / 等效PIO周期 | > 95% |
| 中断合并率 | 每次中断处理的DMA完成事件数 | 4~64(可配置) |
课程预告:第2章将介绍如何搭建DMA性能测试环境,包括硬件要求、内核配置和
dmatest模块的加载方法。