GPU执行与访存
全库目录221
本文目录9
同一段Shader在一台设备上受纹理访问限制,换到另一台可能被寄存器或计算吞吐卡住。只看指令行数很难解释差异。我们先追踪线程怎样组织、地址怎样访问,再用保持输出一致的对照实验,把代码行为与目标计数器联系起来。
Wave、延迟隐藏与占用率
一个 wave/warp 内的线程按硬件执行模型处理指令,分支可能屏蔽部分 lane。较高占用率提供更多候选 wave,帮助隐藏内存等待,但占用率最高不保证耗时最低。寄存器、共享内存、线程组大小和执行单元共同限制驻留。
GPU 计数器的单位和归一化方法由工具决定。“百分比低”不能单独证明资源闲置;需要检查它的分母、采样窗口和同时发生的限制。
延迟隐藏可以用一条简化时间线理解:wave A在时刻0发出访存,结果要到时刻100才就绪;若它下一条指令依赖该值,A会等待。wave B此时有独立算术指令,调度器可以执行B,随后再选C。足够多的就绪工作可以填满这段空隙,但若A、B、C都等待同一类带宽饱和的请求,增加驻留wave不能增加总线吞吐。这里的100是教学时间单位,调度粒度与实际延迟由目标硬件决定。
缓存与访问模式
连续线程访问连续地址有利于合并事务。每线程访问不同纹理、随机索引或跨大 stride,会增加事务或降低缓存命中。压缩纹理减少部分带宽,仍需解码与过滤。
可先用地址分布建立假设。设一个32线程批次每线程读4字节,事务粒度暂按32字节、首地址按32字节对齐。连续地址覆盖128字节,落在4段中;每线程跨128字节则落在32段中。读取的有效数据仍是128字节,但后者需要触及更多事务段。这里的32线程和32字节仅用于算例,目标设备的wave宽度、缓存行、广播及合并规则需查手册。
占用率也受离散资源分配限制。假设某计算单元有65536个32位寄存器,每线程用64个、每wave32线程,仅按寄存器上限可驻留32个wave;增加到65个后,上界降为31,实际分配粒度还可能进一步降低。减少寄存器若造成溢出访存,总耗时反而可能增加,因此观察编译统计后还需测关键路径。
统一内存设备减少部分复制路径,CPU/GPU 的可见性、缓存和执行同步仍然存在。回读等待的主要代价可能是整条流水线停顿,不能只按字节数估算。
直接与分块渲染
立即模式 GPU 和分块 GPU 的前端、遮挡处理、附件驻留不同。Tile GPU 常在片上处理颜色、深度与 MSAA,减少附件主存访问。过多 MRT、大格式或样本数会增加片上压力,切换通道或采样完整图像可能产生存储与加载。
API render pass 有助于表达附件使用范围,但是否保留片上、如何合并由实现决定。不要把某一厂商的隐面消除能力写成所有移动 GPU 的规则。
逻辑流量估算
下面估算 RGBA16F 全屏读写,输入是尺寸和帧率,输出为理论字节数。它不包含缓存、压缩、额外采样和深度访问。
width, height = 1920, 1080
bytes_per_pixel = 8
read_bytes = width * height * bytes_per_pixel
write_bytes = width * height * bytes_per_pixel
traffic_per_frame = read_bytes + write_bytes
traffic_per_second = traffic_per_frame * 60
print(traffic_per_frame / 1_000_000)
print(traffic_per_second / 1_000_000_000)理论完整读写约33.18MB/帧、1.99GB/s,这不是外部总线流量下限。实际流量需计数器确认;片上复用和压缩可能降低外部流量,多次采样或存储转换可能增加它。该算式用于建立量级与实验假设。
控制变量实验
| 变化 | 观察 | 可支持的假设 |
|---|---|---|
| 降低分辨率 | GPU 时间明显下降 | 像素、采样或附件成本较高 |
| 简化像素 Shader | 时间下降且覆盖相同 | 着色或纹理路径受限 |
| 降低几何密度 | 几何阶段与整帧下降 | 顶点、装配或微三角形受限 |
| 改访问顺序 | 事务与耗时下降 | 局部性或访问合并问题 |
| 开关异步队列 | 关键路径变化 | 重叠收益或资源竞争 |
多种成本可以同时存在。实验改变一个因素后,应检查实际资源和执行路径未被设置联动改变。
API 差异的影响
D3D12、Vulkan 和 Metal 都允许显式表达资源与提交,但绑定、同步、内存和附件模型不同。OpenGL 的状态机与驱动隐式管理可能掩盖这些步骤。跨平台设计要统一工程职责,保留后端语义的精确表达。
验证方法
记录设备型号、驱动、API、分辨率与构建配置。预热后取稳定窗口和多次样本,结合 GPU 阶段时间、外部流量、纹理事务与占用率。计数器说明来自目标工具手册;无法取得计数器时以可控实验支持较窄的结论。
相关主题
实现与验证:Python流量算式可独立执行,结果为33.1776MB/帧和1.990656GB/s;事务与寄存器示例采用文中假定的粒度,仅用于解释计数关系。没有目标GPU计数器或性能结果。
参考资料
- Arm Tile-based GPUs,分块渲染和带宽。
- NVIDIA Nsight Graphics 与 AMD Radeon GPU Profiler 官方计数器文档。
- Vulkan GPU Memory。
- NVIDIA CUDA Best Practices 13.4:2026-10-22核读§10.2.1访问合并与§11.1占用率;事务算例对应文中明确的粒度,跨厂商使用时重新核对。