GPU(Graphics Processing Unit,图形处理器)是面向大规模并行图形渲染和通用计算的处理器;它通常由 CPU 通过驱动提交命令,在大量执行单元上并行处理顶点、像素、纹理、矩阵和计算任务。
GPU 的关键不是“比 CPU 更快”,而是它适合把同一种操作同时应用到大量数据上,例如每个像素、每个顶点或每个矩阵元素。
核心问题
图形渲染和很多数值计算都有共同特点:
- 数据量大,例如一帧图像有几百万个像素。
- 每个元素的计算相似,例如同一个着色器应用到许多顶点或像素。
- 可以容忍大量任务并行排队,而不是每一步都严格串行。
- 内存带宽、缓存局部性和批量提交比单个指令延迟更重要。
CPU 更擅长复杂控制流、系统调用、任务调度和低延迟分支;GPU 更擅长吞吐量型并行计算。现代图形系统通常由 CPU 构建命令,GPU 异步执行命令。
核心对象
| 对象 | 作用 | 工程关注点 |
|---|---|---|
| command buffer | CPU 准备、GPU 执行的命令序列 | 记录顺序、提交队列、同步 |
| shader | 在 GPU 执行的小程序 | 顶点、片元、计算、编译和驱动兼容性 |
| buffer / image | GPU 访问的数据资源 | 内存位置、格式、布局、生命周期 |
| queue | 接收 GPU 工作的队列 | 图形、计算、拷贝、优先级 |
| VRAM / shared memory | GPU 使用的存储 | 带宽、容量、映射、缓存一致性 |
| fence / semaphore | CPU-GPU 或 GPU-GPU 同步 | 何时能读、写、复用资源 |
核心机制
GPU 工作通常不是 CPU 调一次函数就马上完成,而是异步提交和执行:
- CPU 通过用户态驱动准备资源和命令。
- 驱动把图形 API 调用翻译成 GPU 能理解的命令缓冲。
- 内核驱动检查权限、内存和同步条件。
- 命令进入 GPU 队列。
- GPU 在大量执行单元上并行运行 shader 或固定功能阶段。
- 完成后写入结果缓冲,并触发 fence 或中断。
- CPU、显示控制器或下一个 GPU 任务等待同步信号后再使用结果。
一个简化模型是:
throughput ~= work_items * work_per_item / execution_timework_items是可并行处理的数据项数量,例如像素数、顶点数或矩阵块数。work_per_item是每个数据项的计算量。execution_time受执行单元数量、内存带宽、调度、同步和分支发散影响。- 这个式子只表达吞吐直觉,不是精确性能公式;真实性能还受缓存、驱动、功耗和硬件架构影响。
工程用途
- 实时 2D/3D 图形渲染、游戏、桌面合成和 UI 动画。
- 视频编解码、图像处理、相机 ISP 后处理和视觉算法加速。
- 机器学习训练和推理中的矩阵乘法、卷积和注意力计算。
- 科学计算、仿真、密码学批处理和数据并行任务。
在 Linux 上,应用通常不直接访问 GPU 寄存器,而是通过 DRM、用户态图形驱动和图形/计算 API 间接提交工作。
边界与常见坑
- GPU 不自动让程序变快:任务必须有足够并行度,并且数据搬运成本不能吃掉收益。
- GPU 和显示控制器不是同一个概念:有些 SoC 有显示输出控制器但没有强 3D GPU;有些 GPU 负责渲染,扫描输出由另一个模块完成。
- 显存容量和带宽都重要:容量不够会溢出或频繁换页;带宽不足会限制帧率或计算吞吐。
- 异步执行容易误判时间:CPU 提交命令很快,不代表 GPU 已完成;性能测量要等 fence 或使用 GPU 时间戳。
- 驱动和用户态库同样关键:硬件存在但驱动、固件或用户态库缺失时,可能只能软件渲染。