4.7 性能:CPU 瓶颈 vs GPU 瓶颈


文档摘要

4.7 性能:CPU 瓶颈 vs GPU 瓶颈 本节摘要:WebGL 掉帧时先分端。CPU 瓶颈表现为主线程长任务:过多 draw、每帧上传、编译、同步读回、场景图遍历。GPU 瓶颈表现为填充率、overdraw、重 FS、大纹理带宽、阴影 pass。优化必须对着那一端:合批减的是 CPU 提交;降分辨率与砍透明减的是 GPU 片元。把两边的药交叉吃,会出现“合批了更慢”或“降画质帧率不变”。本节用对照表收束全文,并把典型案例写成误诊对照,而不是外链作品集。

4.7 性能:CPU 瓶颈 vs GPU 瓶颈

本节摘要:WebGL 掉帧时先分端。CPU 瓶颈表现为主线程长任务:过多 draw、每帧上传、编译、同步读回、场景图遍历。GPU 瓶颈表现为填充率、overdraw、重 FS、大纹理带宽、阴影 pass。优化必须对着那一端:合批减的是 CPU 提交;降分辨率与砍透明减的是 GPU 片元。把两边的药交叉吃,会出现“合批了更慢”或“降画质帧率不变”。本节用对照表收束全文,并把典型案例写成误诊对照,而不是外链作品集。

学习目标

阅读完本节,你应当能够:

  1. 用性能面板区分主线程时间与 GPU 时间
  2. 列出至少五项 CPU 税与五项 GPU 税
  3. 说明合批、实例化、减少状态切换为何是同一类 CPU 药
  4. 说明降 drawingBuffer、减透明、早深度、mip 为何是 GPU 药
  5. 对“电商查看器卡顿”和“粒子页卡顿”给出不同的首要怀疑

同一句“卡”,两张药方

用户只说卡。你要问是操作也卡(主线程阻塞输入),还是画面顿、输入还跟手(GPU 或呈现)。readPixels、大数组排序、JSON 解析会堵输入。复杂 Bloom 加 4K 屏会顿画面。工具:浏览器性能记录、可选的扩展计时。没有记录就改着色器,属于猜。

全文的四组对照在这里合成诊断:版本决定你有没有实例化与 MRT 这些减税工具;可编程让 FS 可以贵到爆;CPU 准备过重时 GPU 空等;引擎合批帮 CPU,自定义材质写炸则帮倒忙。

帧时间 ≈ CPU 准备 + 等待GPU + GPU执行 + 合成 优化只砍其中最大项

税表与药表

CPU 税 症状 错药
draw 过多 物体一多就卡,GPU 利用率不高 合批、实例化 简化 FS
每帧 bufferData 动画卡、GC STATIC + 蒙皮或公式 再加一张 4K 贴图
每帧编译 偶发卡一下 预热 program 换过滤模式
readPixels 同步 整帧尖刺 留 GPU 或小 FBO 偶发读 开 MSAA
getUniformLocation 热路径 中等物体数就卡 缓存位置 减灯光视觉质量
场景图无剔除 CPU 遍历全世界 视锥剔除 阴影分辨率加倍
GPU 税 症状 错药
overdraw 透明 填充率满 减层、预乘、从前向后不透明 再合批更多透明
重 FS / PBR 全槽 大屏掉帧 减槽、移动档材质 微减 draw 数
无 mip 大图 远景闪且带宽 建 mip、缩源图 加各向异性硬撑
阴影高分辨率多 cascade pass 时间长 降尺寸、减投射者 关垂直同步当优化
画布 backing store 过大 手机发烫 限制 drawingBuffer 继续提高 CSS 尺寸
discard 破坏早深度 树叶很贵 几何更贴、少 discard 关深度

图:两端账单与常见案例

图:两端账单与常见案例

案例误诊对照(替代空泛作品集)

案例 A:产品查看器转模型掉帧。误诊“显卡不行”,加了更贵的环境反射。真因常是 canvas 按设备像素比拉到 3x,FS PBR 全槽。药:cap 像素比、移动档减槽。这是 GPU。若模型零件上千且每个 Mesh 一次 draw,则先合批,那是 CPU。同一产品两种病,不能只记“查看器要优化阴影”。

案例 B:数据大屏折线。误诊简化着色。真因每帧从业务数组 new Float32Array 上传。药:环状缓冲 SubData,或点数量降采样。GPU 几乎闲。

案例 C:粒子节日页。加法混合全屏 overdraw,GPU 死。合批粒子到一次 draw 后 CPU 好了,画面更烫,因为更密的透明。药:限粒子数、降分辨率离屏再上屏、用预乘加法少采样。合批必要但不充分。

案例 D:从 WebGL1 迁 2.0 期望加速。若仍每帧 vertexAttribPointer、无 VAO、无实例化,合同换了习惯没换,帧时间几乎不动。2.0 不是性能开关,第 1.1 节说过。

引擎统计面板给出的 draw call、三角形、纹理内存要对照两端:draw call 高先看 CPU;三角形高且都在屏上才看 GPU;纹理内存高两边都可能(上传卡 CPU,采样卡 GPU)。不要只盯三角形数一个指标。

⚠️ 常见坑:在 CPU 瓶颈上降阴影贴图尺寸,数字好看、用户无感;在 GPU 瓶颈上做对象池,内存整齐、填充率照旧。记录前后帧时间,且分端。

💡 关键直觉:优化是减法。先减错误的工作(每帧上传静态网、全屏透明),再减正确但过贵的工作(PBR 槽、cascade)。加复杂缓存是最后一步。

电量与发热是移动端的第三张账单,常跟 GPU 填充绑定。桌面 60 帧不等于手机可接受。锁 30 帧加低 drawingBuffer,有时比“优化着色器 10%”更像产品。对照要写进档位:高档桌面、中档手机、低档关后处理。档位是效果路线表的运行时版。

问题:有没有一份永远正确的最佳实践清单?

没有。清单会过期,分端问题不会。你会遇到新的引擎、新的扩展、将来的 WebGPU,问句仍是:数据现在停在哪一端、合同是哪一份、变化粒度是什么。本文集反复练的是这三问。技巧条目可以丢,三问留下。

档位表、测量纪律、以及优化的停止条件

把效果路线收成三档。低档:WebGL1 或 2 均可,无阴影贴图、无后处理、半球光、POT 贴图、像素比 1。中档:平面影或 512 贴图、一层模糊、方向光逐片元、像素比 1.5。高档:级联或 1024 贴图、PBR 槽、IBL、像素比 2 cap。启动时按包等级与 GPU 时间预算选档,允许用户手动升。档位是 4.1 到 4.6 的运行时开关,不是另写三套引擎。

测量纪律:改动一次只动一个变量;记录 CPU 与 GPU 时间、draw 数、三角形、纹理内存;真机再测一次。开发机上合批的收益会被过强 GPU 藏住。停止条件:帧时间稳定在预算内,且下一刀要砍的是产品不接受的外观。没有停止条件,优化会吃掉材质。预算数字写进项目说明,例如手机 22 毫秒、桌面 16 毫秒。超了才开刀。

呈现与 vsync:浏览器合成不在你的 draw 里。CSS 滤镜、半透明 DOM 叠在 canvas 上,会让合成变贵,看起来像 WebGL 慢。对照方法:全屏 canvas 无 DOM 叠层测一次。若这时满帧,优化 DOM 而不是 FS。两端之外还有第三端:浏览器合成。本文集主讲 GL 两端,但诊断时不要忘了页面。

最后回到四组对照。版本给不给你实例化与 MRT;管线决定贵的公式在着色器;CPU 准备是否在搬砖;封装是否藏了多余 draw。优化会变成选择题而不是祈祷。这就是对比驱动贯穿到收口的原因:不问“还有什么技巧”,问“现在最大的账单在哪一格”。

合批实践顺序,以及停止后的回归

合批顺序建议:先静态不透明按 program 排;再处理实例化同类;最后才动透明。透明合批收益小风险大。每一步测分端时间。回归:加新效果必须复测档位机。Bloom 能把中档打回 GPU 瓶颈。把性能测试写成清单挂在第 4.7 节旁边:draw 数、像素比、阴影尺寸、PBR 槽数。清单比灵感可靠。优化结束后删调试全屏四边形与 getError 循环,避免调试税留在生产。

对照问答:合批更慢、降画质无效、DOM

合批之后更烫?

透明合批增加了重叠填充。CPU 好了 GPU 死了。分端记录会显示 GPU 升。药是减层或降分辨率,不是继续合。合批只治 draw 税。

把阴影关了帧率不变?

瓶颈不在阴影。可能在 drawingBuffer 或 PBR 槽或 DOM 合成。关一项测一项。不变就不是它。同时关五件无法归因。纪律比直觉重要。

WebGL 很轻但页面仍卡?

CSS 滤镜、半透明叠层、大 DOM。全屏只留 canvas 测。满帧则治页面。第三端是合成。优化 GL 救不了滤镜。对照要包含这一端,否则 4.7 会误诊。

工程备忘:档位机与改动门禁

固定三台档位机。每次效果合入在三台测 CPU GPU 时间、draw、像素比、槽数。超预算打回。改动一次一事。调试 getError 循环禁止进主分支。DOM 叠层测试列入清单。停止条件写进项目说明。优化任务必须标明打的是 CPU 还是 GPU。不标明不接。回归用同一场景同一相机。没有固定场景的优化数字不可比。数字不可比就会变成感觉。感觉正是本教程反对的东西。对照要有尺子,尺子就是档位机加分端时间。

优化任务模板强制填:打 CPU 还是 GPU、预期指标、档位机编号、停止条件。不填不排期。合批更烫的案例写进团队 wiki 式备忘,防止重复交叉吃药。drawingBuffer cap 作为低档默认,而不是事后急救。DOM 叠层测试每月做一次,避免运营加滤镜把合成打爆还怪 WebGL。固定场景固定相机的录屏当回归基线。没有基线的数字会打架。打架时回到两端尺子:主线程长还是 GPU 长。尺子是第 2.1 节给全书的礼物,本章只是把它用到收口。收口之后若还想加技巧,先加档位,再加技巧。没有档位的技巧是库存,不是产品。

每次优化合入在三台档位机留下前后数字。没有数字的“感觉快了”不准合。感觉会被开发机独显骗。骗过之后手机发烫。发烫先看 drawingBuffer 与透明层数,这是 GPU。再看 draw 数,这是 CPU。两行数字决定下一刀。刀要停,停在预算内。预算写在说明里,说明比聊天记录硬。

现场对照时只改一个变量。同时改版本、封装、通道,归因会消失。消失之后只能靠感觉,感觉正是本书要拆掉的东西。把改动写成一条,测完再写下一条。一条一条,四组对照才用得上。用不上的对照表只是装饰。装饰填不满格子,格子空着就不要标完工。优化这一格改完,三台档位机留数字,不要用开发机感觉合入。数字要分 CPU 与 GPU 两行。少一行就还会交叉吃药。交叉吃药会砍外观却留卡顿,卡顿再回来时已经没有可砍的槽。先分端,再动刀,刀停在预算内。预算写进说明,说明比感觉硬。感觉来自开发机独显,独显不会替渠道里的手机付钱。手机预算用 22 毫秒,桌面用 16 毫秒,超了才开刀。开刀前先写打的是 CPU 还是 GPU,不写就不排期。这是本章也是全书的收口纪律。纪律让对照表从装饰变回尺子。尺子就是分端时间,不是技巧清单。清单会过期,分端问题不会过期。留住问题。

本节速览

  • 先分端:主线程对 GPU 时间,决定药方。
  • CPU 药:合批、实例化、缓存位置、禁止热路径编译与读回。
  • GPU 药:降 drawingBuffer、减 overdraw、mip、减阴影与 PBR 槽。
  • 合批不是万能:透明合批可能加重填充。
  • 版本不是开关:迁 2.0 要改习惯才能减税。
  • 案例服务于误诊:查看器、折线、粒子、迁版本,各打一端。

读到这里,四组对照应当能叠在同一张诊断表上。遇到新效果,先选路,再跟数据走,最后才谈微优化。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U