← ALL ARTICLES

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 全屏读写,输入是尺寸和帧率,输出为理论字节数。它不包含缓存、压缩、额外采样和深度访问。

python
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计数器或性能结果。

参考资料