gpu驱动中的MMIO和CP

在 GPU 驱动(尤其是现代图形驱动,如 Linux DRM 驱动中的 amdgpui915 等)中,MMIO 和 CP 是两种关键的与 GPU 通信和控制的方式。

它们分别代表不同的硬件交互机制,适用于不同场景。下面将深入浅出地解释这两个概念。

 

一、MMIO(Memory-Mapped I/O)

1. 什么是 MMIO?

MMIO 全称是 Memory-Mapped Input/Output(内存映射输入/输出)。它是一种 CPU 与外设(如 GPU)通信的方式:

把设备的寄存器地址映射到 CPU 的内存地址空间中,CPU 通过读写这些“内存地址”来控制硬件。

换句话说,GPU 的控制寄存器(比如启动引擎、设置状态、读取中断标志等)被“挂”在系统的物理内存地址上。驱动程序通过 mmap() 或内核的 ioremap() 将这些物理地址

映射到虚拟地址,然后像访问普通内存一样读写它们。

2. MMIO 的特点

  • 低延迟、直接控制:适合配置寄存器、查询状态、触发小操作。
  • 由 CPU 主动发起:每次读写都消耗 CPU 周期。
  • 带宽有限:不适合传输大量数据(如纹理、顶点)。
  • 同步操作:写入后通常立即生效(或在 GPU 的寄存器流水线中很快处理)。

3. 在 GPU 驱动中的用途

  • 初始化 GPU(设置时钟、电源域、中断使能等)
  • 启动命令处理器(CP)
  • 查询 GPU 状态(是否空闲、错误状态等)
  • 提交小型命令或 fence 信号
  • 控制显示引擎(配合 KMS 设置分辨率等)

 

示例(伪代码):

// 映射 GPU 寄存器基地址
void __iomem *mmio = ioremap(gpu_mmio_base, mmio_size);

// 写入寄存器:启动某个引擎
writel(0x1, mmio + ENGINE_START_REG_OFFSET);

  

二、CP(Command Processor / Command Processor Ring)

1. 什么是 CP?

CP 是 GPU 内部的一个专用硬件单元,全称通常是 Command Processor(命令处理器),有时也叫 Graphics Command Processor。
它的作用是:从内存中读取预先准备好的命令流(command buffer),并逐条解析、分发给 GPU 的各个引擎(如 3D 引擎、视频解码器、DMA 引擎等)执行。

驱动并不直接通过 MMIO 发送每一条绘图命令,而是:

  1. 在系统内存或显存中构建一个“命令缓冲区”(command buffer);
  2. 通过 MMIO 通知 CP 去读取这个缓冲区;
  3. CP 自动 fetch & execute 这些命令,无需 CPU 干预。

这类似于“批处理”模式,极大提升效率。

2. CP 的工作方式(Ring Buffer 模型)

大多数现代 GPU 使用 环形缓冲区(Ring Buffer) 作为 CP 的命令队列:

  • 驱动向 ring buffer 的“尾部”写入新命令;
  • GPU 的 CP 单元从“头部”读取并执行;
  • 通过两个寄存器(HEAD / TAIL)协调进度(通常 TAIL 由 CPU 写,HEAD 由 GPU 更新);
  • 当 TAIL 更新后,CP 自动开始处理新命令。

这种方式实现了 异步、批量、高吞吐 的 GPU 控制。

3. CP 的优势

  • 高吞吐量:一次提交成百上千条命令,避免频繁 MMIO 开销。
  • 降低 CPU 占用:命令执行期间 CPU 可以去做其他事。
  • 支持复杂操作:如 draw call、纹理上传、同步 fence、上下文切换等。
  • 天然支持多任务/多上下文:不同应用的命令可排队执行。

4. 在驱动中的体现

  • Mesa(用户空间)生成 OpenGL/Vulkan 命令 → 打包成 GPU 原生指令(IB: Indirect Buffer);
  • 内核 DRM 驱动将 IB 放入 ring buffer;
  • 驱动通过 MMIO 写 TAIL 寄存器,通知 CP 有新工作;
  • GPU 执行完成后,可能触发中断通知 CPU。

示例流程(AMD GPU):

用户程序 → Mesa → 提交 IB 到 amdgpu 驱动
amdgpu 驱动将 IB 地址写入 GFX ring buffer
写 MMIO 寄存器更新 TAIL 指针
CP 单元自动 fetch IB 并 dispatch 给 shader engines
执行完成,触发 IRQ,驱动回收资源

三、MMIO vs CP:对比总结

特性MMIOCP(Command Processor)
通信方式 CPU 直接读写 GPU 寄存器 CPU 提交命令缓冲区,GPU 自主执行
粒度 单个寄存器操作 批量命令(draw calls、state changes 等)
性能 低延迟,但高 CPU 开销 高吞吐,低 CPU 占用
用途 初始化、控制、状态查询、启动 CP 实际图形/计算 workload 执行
同步性 同步(写即生效) 异步(提交后 GPU 后台执行)
类比 “手动拧螺丝” “把图纸交给机器人流水线”

四、实际例子:AMD GPU 中的 CP

amdgpu 驱动中:

  • 存在多个 ring(GFX ring、Compute ring、DMA ring 等),每个对应一类工作负载;
  • 每个 ring 都由一个 CP 单元管理;
  • 驱动通过 amdgpu_ib_schedule() 提交 indirect buffer;
  • 最终通过写 mmio + mmGRBM_CP_RB_CNTL 等寄存器更新 TAIL。

而在 Intel i915 驱动中,类似机制称为 execlist 或 ringbuffer submission,也是基于命令缓冲区 + MMIO 触发。

五、为什么需要两者结合?

  • MMIO 是“控制通道”:用于 setup、teardown、紧急干预;
  • CP 是“数据通道”:用于高效执行实际 workload;

没有 MMIO,无法启动 CP;
没有 CP,GPU 只能做非常简单的操作,无法发挥现代 GPU 的并行能力。

 

总结

  • MMIO:CPU 通过内存映射直接操控 GPU 寄存器,适合精细控制和初始化。
  • CP:GPU 的命令处理器,通过 ring buffer 异步执行大批量命令,是高性能渲染的核心。

二者相辅相成,构成了现代 GPU 驱动与硬件交互的“双轮驱动”模型。



posted on 2025-12-05 14:41  lh03061238  阅读(3)  评论(0)    收藏  举报

导航