1. DMA 基础概念

1.1 DMA 定义

DMA(Direct Memory Access,直接存储器访问) 是一种允许硬件设备(如网卡、磁盘控制器、GPU)直接与系统内存交换数据,而无需 CPU 逐字节参与的 I/O 技术。DMA 控制器(DMAC)作为独立的总线主控设备,在系统总线上与 CPU 并行工作,完成数据块的高速搬运。

核心要点: DMA 的本质是“CPU 授权,硬件自治”。CPU 只需设置源地址、目的地址、传输长度和方向,DMA 控制器即可独立完成剩余操作,并在传输结束后通过中断通知 CPU。

1.2 DMA 与 CPU 数据搬运对比

传统 PIO(Programmed I/O)模式下,CPU 必须亲自执行每一条加载/存储指令来搬运数据;而 DMA 模式下,CPU 仅参与初始化与收尾。下表从多个维度对比两种方式:

对比维度 PIO(CPU 搬运) DMA 搬运
CPU 占用率 高(100% 占用直到传输完成) 低(仅初始化 + 中断处理,约 1-5%)
吞吐量 受限于 CPU 主频与指令吞吐 接近总线带宽上限(如 PCIe Gen4 x16 约 32 GB/s)
延迟 单字节延迟低,但大块传输累积延迟高 启动延迟略高(约 1-2 μs),但块传输延迟极低
适用数据量 小数据(< 64 字节,如寄存器读写) 大数据(≥ 512 字节,如网络帧、磁盘块)
硬件复杂度 无需额外控制器 需要 DMAC 或设备内置 DMA 引擎
Cache 一致性 天然一致(CPU 直接访问) 需软件或硬件维护一致性(如 cache 刷新/无效化)
性能量化参考: 在 2.5 GHz 的 x86 CPU 上,PIO 搬运 1 MB 数据约需 500 μs(含循环开销),而 DMA 搬运同样数据仅需约 10 μs(PCIe 延迟 + 传输时间),性能提升约 50 倍。

1.3 DMA 传输优势与适用场景

DMA 的核心优势可归纳为以下四点:

  • CPU 卸载: 将 CPU 从繁重的数据搬运中解放出来,使其专注于协议处理、计算和控制逻辑。
  • 高吞吐: 利用总线突发传输(burst transfer)模式,单次 DMA 请求可传输多个数据字,充分利用总线带宽。
  • 低延迟: 硬件级流水线操作,无需软件循环和中断上下文切换。
  • 并行性: DMA 传输与 CPU 执行指令可完全重叠(overlap),实现真正的并行处理。

典型适用场景包括:

场景 说明 典型数据量
网络数据收发 网卡 RX/TX 描述符环 + DMA 直接将帧写入/读出内存 64 B ~ 9 KB(Jumbo Frame)
存储 I/O NVMe / AHCI 控制器通过 DMA 在内存与磁盘间搬运扇区 512 B ~ 2 MB
GPU 显存传输 PCIe DMA 引擎在主机内存与显存之间搬运纹理/顶点数据 1 MB ~ 数 GB
多媒体采集 摄像头/采集卡通过 DMA 将视频帧直接送入内存缓冲区 数百 KB ~ 数十 MB
高速数据采集 ADC/DAC 设备通过 DMA 连续传输采样数据 持续流,无固定块大小

1.4 DMA 传输基本流程(内联 SVG)

下图展示了一次典型 DMA 传输的完整生命周期,从 CPU 初始化到传输完成中断:

DMA 传输基本流程 CPU 初始化 DMAC DMAC 请求总线控制 DMAC 执行数据传输 传输完成,释放总线 DMAC 发送中断给 CPU CPU 中断处理 & 数据消费 关键说明 • CPU 设置源/目的地址、长度、方向 • DMAC 独立搬运,CPU 可执行其他任务 • 中断触发后 CPU 处理数据 CPU 并行活动 • 执行协议栈处理 • 响应其他中断 • 调度其他任务

1.5 DMA 传输模式分类

根据总线控制权的管理方式,DMA 分为以下三种模式:

  • 块传输(Block Transfer): DMAC 获得总线控制权后,连续传输整个数据块,传输期间 CPU 无法访问总线。适用于高速、大批量数据传输。
  • 周期窃取(Cycle Stealing): DMAC 在每个总线周期中“窃取”一个时钟周期进行传输,然后释放总线。适用于中等速率设备,对 CPU 影响较小。
  • 透明传输(Transparent Transfer): DMAC 仅在 CPU 不使用总线时(如 CPU 执行内部操作)进行传输。对 CPU 性能影响最小,但硬件实现复杂。
工程注意: 在 Linux 网络驱动中,块传输是最常用的模式。网卡 DMA 引擎通过描述符环(Descriptor Ring)管理多个数据缓冲区的链式传输,实现零拷贝(Zero-Copy)收发包。周期窃取模式多见于低速嵌入式系统,透明传输则较少使用。

1.6 DMA 地址空间与一致性

DMA 操作涉及三种地址空间:

地址类型 说明 示例
CPU 虚拟地址 内核/用户态软件使用的地址 0xffff8881a2b3c000
CPU 物理地址 内存总线上的真实物理地址 0x1a2b3c000
DMA 总线地址 设备侧看到的地址(经 IOMMU 映射) 0x10000000

在启用 IOMMU(如 Intel VT-d、AMD IOMMU)的系统中,DMA 总线地址与 CPU 物理地址可能不同。驱动必须使用 dma_alloc_coherent() 或 dma_map_single() 等 API 进行地址转换和一致性管理。

一致性模型:
  • 一致性 DMA(Coherent DMA): 硬件保证 cache 与内存一致性,适用于小数据量、频繁访问的场景(如描述符环)。
  • 流式 DMA(Streaming DMA): 软件通过 cache 刷新/无效化维护一致性,适用于大数据块传输(如网络帧数据)。

1.7 小结

DMA 是现代高性能设备驱动的基石。通过将数据搬运任务从 CPU 卸载到专用硬件控制器,DMA 实现了:

  • CPU 利用率从 100% 降至 1-5%
  • 吞吐量提升 10-50 倍(取决于总线带宽)
  • CPU 与 I/O 的并行执行