cleanup
This commit is contained in:
@@ -1,342 +0,0 @@
|
|||||||
---
|
|
||||||
title: "如何正确高效的查找游戏「卡顿」原因? - 知乎"
|
|
||||||
source: "知乎"
|
|
||||||
url: "https://www.zhihu.com/question/28824284/answer/1965456096262096583"
|
|
||||||
date: 2026-06-10 22:49
|
|
||||||
tags: [zhihu, saved]
|
|
||||||
---
|
|
||||||
|
|
||||||
关注
|
|
||||||
推荐
|
|
||||||
热榜
|
|
||||||
专栏
|
|
||||||
圈子
|
|
||||||
New
|
|
||||||
付费咨询
|
|
||||||
故事
|
|
||||||
|
|
||||||
直答
|
|
||||||
切换模式
|
|
||||||
登录/注册
|
|
||||||
如何正确高效的查找游戏「卡顿」原因?
|
|
||||||
关注问题
|
|
||||||
|
|
||||||
写回答
|
|
||||||
登录/注册
|
|
||||||
游戏
|
|
||||||
程序员
|
|
||||||
编程
|
|
||||||
Unity(游戏引擎)
|
|
||||||
如何正确高效的查找游戏「卡顿」原因?
|
|
||||||
背景:我在一家创业公司,我们开发了一些独立的小游戏。最近在做的一款小游戏,使用了 Unity 引擎,在研发快要完成时,我们忽然发现:游戏偶尔会卡一下,…显示全部
|
|
||||||
关注者
|
|
||||||
206
|
|
||||||
被浏览
|
|
||||||
37,144
|
|
||||||
关注问题
|
|
||||||
写回答
|
|
||||||
|
|
||||||
邀请回答
|
|
||||||
|
|
||||||
好问题 1
|
|
||||||
|
|
||||||
1 条评论
|
|
||||||
|
|
||||||
分享
|
|
||||||
|
|
||||||
登录后你可以
|
|
||||||
不限量看优质回答私信答主深度交流精彩内容一键收藏
|
|
||||||
登录
|
|
||||||
查看全部 12 个回答
|
|
||||||
知秋
|
|
||||||
游戏性能优化
|
|
||||||
|
|
||||||
关注
|
|
||||||
|
|
||||||
专栏文章汇总,持续更新:
|
|
||||||
|
|
||||||
高通 Adreno GPU 最佳实践 0--汇总 - 知乎
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
参考:Game Developer Guide - Snapdragon Game Toolkit Documentation
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
应用的帧率是多少?
|
|
||||||
|
|
||||||
在使用骁龙分析器(Snapdragon Profiler)之前,你可能已经察觉到应用存在性能问题。即便尚未察觉,也建议先分析应用当前的整体性能,以定位性能瓶颈。
|
|
||||||
|
|
||||||
帧率是分析的理想起点。游戏的最佳运行帧率通常为30帧/秒(fps)或60帧/秒,而虚拟现实(VR)和扩展现实(XR)应用的目标帧率有时会更高。
|
|
||||||
|
|
||||||
帧率分析需关注两个维度:
|
|
||||||
|
|
||||||
平均帧率:衡量应用的平均运行速度;
|
|
||||||
|
|
||||||
帧率稳定性:即便平均帧率接近目标值,若偶尔出现“长帧”(单帧耗时过长),仍可能达不到目标帧率。这会导致用户体验卡顿、画面异常,运动效果不流畅,此时应用亟需优化。
|
|
||||||
|
|
||||||
若应用未经优化,平均帧率可能低于目标值,无法达到理想性能水平;若已完成初步优化,平均帧率可能更接近目标,但仍会周期性出现帧率峰值波动。这些波动会影响动画流畅度,因此需要定位问题根源并修改代码,以实现帧率平稳。
|
|
||||||
|
|
||||||
无论上述哪种情况,骁龙分析器都能直接显示应用的实时帧率性能。下方截图中,浅蓝色线条代表平均帧率,数值为42.022帧/秒。
|
|
||||||
|
|
||||||
虽然42帧/秒的平均帧率可能勉强可用,但蓝色线条(实时帧率)会周期性降至37.322帧/秒的低点。这表明应用存在丢帧现象,会对性能造成负面影响。
|
|
||||||
|
|
||||||
另需注意:应用应选择与平台垂直同步(Vsync)速率成“约数”或“倍数”的帧率作为目标。由于多数平台的垂直同步速率为60Hz,因此30Hz(60Hz的约数)或60Hz(与垂直同步速率一致)是仅有的合理目标帧率。
|
|
||||||
|
|
||||||
探究潜在性能瓶颈
|
|
||||||
|
|
||||||
单一指标无法完整揭示性能问题的位置及解决方案,但骁龙分析器可提供数十种指标,帮助你理解应用与硬件的交互方式。
|
|
||||||
|
|
||||||
在追踪捕获(Trace Capture)模式的截图中,以下三个重要指标可作为分析起点:
|
|
||||||
|
|
||||||
1. 渲染阶段(Rendering Stage)
|
|
||||||
|
|
||||||
骁龙分析器中的“渲染阶段”指标,代表应用在GPU上的执行过程。每个数据轨道(track)都是该指标的一个子集,轨道数量会因应用而异。在下方截图中,绿色、品红色和紫色区块代表各个独立的表面(surface),而“表面”区块下方的轨道则对应相关的渲染阶段。
|
|
||||||
|
|
||||||
2. GPU活动(GPU Activity)
|
|
||||||
|
|
||||||
这是一项系统级指标,用于展示CPU与GPU之间的交互情况。
|
|
||||||
|
|
||||||
3. CPU调度(“Trace Kernel - Sched CPU”)
|
|
||||||
|
|
||||||
同样是系统级指标,可概览应用在每个CPU核心上的执行状态。通过该指标,你能查看应用的不同模块在哪个核心上运行,以及是否存在调度问题或线程竞争问题。
|
|
||||||
|
|
||||||
借助上述指标,可探究性能可能受限的三个核心领域:GPU、CPU 和 垂直同步(Vsync,即显示器的垂直同步刷新机制)。
|
|
||||||
|
|
||||||
受GPU限制的应用(GPU-bound application)
|
|
||||||
|
|
||||||
对于图形密集型应用,建议优先排查是否受GPU性能限制。
|
|
||||||
|
|
||||||
在骁龙分析器的实时视图(Real-Time view) 中,“GPU利用率(GPU % Utilization)”是核心指标。下方第一张截图显示,GPU利用率在26%-38%之间波动:
|
|
||||||
|
|
||||||
对比下方第二张截图——GPU利用率稳定在98%-100%:
|
|
||||||
|
|
||||||
后者强烈表明,应用正受GPU性能限制(即GPU处理能力不足,成为性能瓶颈)。
|
|
||||||
|
|
||||||
除实时视图外,骁龙分析器的追踪捕获模式也能提供参考依据:若应用不受GPU限制,GPU活动轨道中可能会出现“空闲间隙”(无GPU任务执行的时间段),如下所示:
|
|
||||||
|
|
||||||
若应用受GPU限制,则GPU执行可能会延迟,且GPU可能处于持续渲染表面的状态,如下所示:
|
|
||||||
|
|
||||||
受CPU限制的应用(CPU-bound app)
|
|
||||||
|
|
||||||
若应用不受GPU限制,则需进一步判断是否受CPU性能限制。
|
|
||||||
|
|
||||||
与GPU受限不同,实时视图中的“CPU利用率(CPU % Utilization)”并非判断应用是否受CPU限制的可靠指标。
|
|
||||||
|
|
||||||
第一张图中应用的平均CPU利用率为16%,第二张图为23%。实际上,第一张图中的应用是受CPU限制的,但两者的利用率差异远不如GPU受限场景中那么显著,因此单看利用率可能误以为应用不受CPU限制。
|
|
||||||
|
|
||||||
判断应用是否受CPU限制,有两个核心标准:
|
|
||||||
|
|
||||||
应用不受GPU限制;
|
|
||||||
平均帧时间超过16毫秒(对应60帧/秒的目标帧率,1秒÷60≈16.67毫秒)。
|
|
||||||
|
|
||||||
此外,还需结合应用的多线程特性及CPU架构综合判断。除“CPU利用率”外,分析“CPU频率”“线程调度”等指标也会对排查有帮助。
|
|
||||||
|
|
||||||
在下方追踪捕获模式的截图中,“Sched CPU 6”(即第6号CPU核心)上的线程似乎成为了CPU的性能瓶颈:
|
|
||||||
|
|
||||||
下一步需深入分析该线程,定位“热点函数”(执行耗时较长的函数),并判断是否可通过多线程优化。骁龙分析器的采样捕获模式(Sampling capture mode) 可按固定时间间隔对CPU程序计数器进行采样,识别CPU的“热点执行路径”。该模式会以统计形式展示CPU活动,包括在每个函数和库中花费的时间,从而帮助你找到代码中执行耗时最长的函数。
|
|
||||||
|
|
||||||
下方采样结果展示了CPU上用于渲染布料纹理的“函数列表”及“函数调用顺序”。红色和橙色区块代表应用代码中的热点(即执行耗时最长的部分):
|
|
||||||
|
|
||||||
在本案例中,CPU采样结果显示SatisfyConstraints()是最大的热点函数,占用了98%的CPU活动时间。
|
|
||||||
|
|
||||||
若需进一步深入分析,骁龙分析器支持“用户标记(user markers)”和Android NDK中内置的“原生追踪API(Native Tracing API)”。Android开发者可通过该API在应用代码中插入追踪标记,随后在骁龙分析器中查看相关数据。
|
|
||||||
|
|
||||||
在下方示例中,可使用android/trace.h对SatisfyConstraints()调用进行插桩(instrument),并追踪到该函数的调用源自“主线程”(一个工作线程函数):
|
|
||||||
|
|
||||||
渲染帧中的某一纹理,需为每块布料调用一次该函数,并根据耗时动态调整执行频率。当修改应用代码,将该函数的执行分配到多个线程后,骁龙分析器可同时显示所有活动的“完整关联视图”:
|
|
||||||
|
|
||||||
此时,布料计算已在多个线程中并行执行。从“CPU调度”指标可看到更多线程活动,应用不再受CPU限制,CPU会等待绘制任务的分发(而非因CPU能力不足导致绘制延迟)。
|
|
||||||
|
|
||||||
以上流程是使用骁龙分析器识别、诊断并解决性能问题的典型案例。
|
|
||||||
|
|
||||||
受垂直同步限制的应用(Vsync-bound app)
|
|
||||||
|
|
||||||
若确定应用既不受CPU限制,也不受GPU限制,则可能受垂直同步(Vsync)限制——即应用的运行速度已达到显示硬件的最大刷新能力。在骁龙分析器的追踪捕获模式中,可能会看到类似下方的画面:
|
|
||||||
|
|
||||||
需注意:此时单帧时间恰好约为16毫秒(对应60帧/秒,1秒÷60≈16.67毫秒),且在帧周期末尾会出现一段“间隙”——期间CPU和GPU均处于等待状态,等待可用的表面(surface)以进行下一帧渲染。
|
|
||||||
|
|
||||||
尽管许多应用的目标是“尽可能达到显示硬件的最大刷新速度”,但即便应用受垂直同步限制,仍存在优化空间,且优化收益不仅限于提升帧率。
|
|
||||||
|
|
||||||
移动应用的多数性能问题最终都与“功耗/电池续航”相关。即便应用通过“受垂直同步限制”(而非受CPU或GPU限制)达到了目标帧率,仍建议优化代码:若能通过修改代码降低功耗、减少设备发热,应用可在“完成更少工作”的同时维持目标帧率,还可能在低端设备上实现更优性能。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
阅读全文
|
|
||||||
|
|
||||||
赞同 72
|
|
||||||
|
|
||||||
添加评论
|
|
||||||
|
|
||||||
314
|
|
||||||
|
|
||||||
7
|
|
||||||
|
|
||||||
分享
|
|
||||||
豆包让小白也能玩转 AI 漫画图片生成
|
|
||||||
豆包让小白也能玩转 AI 漫画图片生成
|
|
||||||
查看详情
|
|
||||||
豆包
|
|
||||||
的广告
|
|
||||||
更多回答
|
|
||||||
王耀威
|
|
||||||
投资合作做游戏找我
|
|
||||||
|
|
||||||
关注
|
|
||||||
|
|
||||||
首先打开profiler,查看所有凸起的线
|
|
||||||
|
|
||||||
一般游戏内卡顿的地方
|
|
||||||
|
|
||||||
游戏战斗过程中在加载资源文件
|
|
||||||
NGUI中图集太乱导致drawcall彪涨
|
|
||||||
|
|
||||||
NGUI中active/unactive导致重建drawcall生成大量的资源
|
|
||||||
频繁创建对象删除对象,没有缓存。
|
|
||||||
unity自身的一些bug,有时候可以看到物理引擎计算的量很大。
|
|
||||||
使用了更精确但更耗时的判断如meshcollider
|
|
||||||
所有逻辑都使用unity主线程处理
|
|
||||||
使用过多复杂的渲染,如一些实时GI或摄像机渲染效果加强
|
|
||||||
string串接foreach,getcomponet等问题
|
|
||||||
|
|
||||||
解决方法
|
|
||||||
|
|
||||||
在游戏战斗开始时前加载所有用到的资源,不要在战斗过程加载资源,因为unity是单线程的模式,如果没有使用异步线程做加载或一开始进入场景时加载,这个问题就很突出了。
|
|
||||||
|
|
||||||
NGUI为了减少GPU状态切换的消耗(比如切换material),把相同material的UIWidget合并,减少Draw Call的数量。这一步是基于UIPanel做的,合并UIWidget的代码可自行查看UIPanel.cs的FillAllDrawCalls()函数,原理如下图,尽量分好层次如背景框,按钮等。
|
|
||||||
NGUI中,active/unactive会删除重建材质drawcall,如果界面内容稍多一些,会导致内存分配,甚至出现drawcall的死循环,目前比较正确的做法是,设置在屏幕坐标外部,然后关闭所有NGUI脚本的运行,NGUI作者的回复截图。
|
|
||||||
|
|
||||||
|
|
||||||
使用对象池缓存一部分频繁使用的资源,不必每次都创建卸载。
|
|
||||||
更新新版本,设置好物理引擎参数。
|
|
||||||
如果没有必要的话,尽量使用速度较快的碰撞检测,入boxcollider。
|
|
||||||
应该合理分离主线程与逻辑线程的关系,比如一些算法采用异步执行的方式,网络数据的解析,加载等,使用代理来把必要的逻辑切换到主线程,不必要的逻辑使用逻辑线程,可以通过一个MonoBehaviour的update来执行代理逻辑
|
|
||||||
有些手机根本无法运行复杂的渲染,能简单尽量简单。
|
|
||||||
字符串串接使用stringbuilder不使用+,频繁foreach最好用for代替,缓存已经取到的componet.
|
|
||||||
阅读全文
|
|
||||||
|
|
||||||
赞同 30
|
|
||||||
|
|
||||||
6 条评论
|
|
||||||
|
|
||||||
59
|
|
||||||
|
|
||||||
11
|
|
||||||
|
|
||||||
分享
|
|
||||||
知乎用户
|
|
||||||
|
|
||||||
分享一点我们自己在做性能优化时的小经验:
|
|
||||||
|
|
||||||
在Unity Editor模式下运行,有部分Overhead是由运行时的场景编辑器导致的,采样的时候可以先把“Scene”关掉。
|
|
||||||
|
|
||||||
用Profiler采样时,首先重点关注CPU占用率高的方法,并且优先打击
|
|
||||||
|
|
||||||
关注内存分配“GC Alloc”,每帧超过100B的内存分配都需要解决,否则这样的的内存分配累积后就会引起GC,很容易引起卡顿
|
|
||||||
|
|
||||||
发布于2015-03-18 11:59
|
|
||||||
|
|
||||||
赞同 11
|
|
||||||
|
|
||||||
9 条评论
|
|
||||||
|
|
||||||
19
|
|
||||||
|
|
||||||
3
|
|
||||||
|
|
||||||
分享
|
|
||||||
|
|
||||||
查看全部 12 个回答
|
|
||||||
下载知乎客户端
|
|
||||||
与世界分享知识、经验和见解
|
|
||||||
广告
|
|
||||||
关于作者
|
|
||||||
知秋
|
|
||||||
游戏性能优化
|
|
||||||
回答
|
|
||||||
21
|
|
||||||
文章
|
|
||||||
33
|
|
||||||
关注者
|
|
||||||
243
|
|
||||||
|
|
||||||
关注他
|
|
||||||
|
|
||||||
发私信
|
|
||||||
大家都在搜
|
|
||||||
换一换
|
|
||||||
清北鹅腿阿姨被曝卖鸭腿
|
|
||||||
419 万
|
|
||||||
热
|
|
||||||
2026 高考数学
|
|
||||||
350 万
|
|
||||||
热
|
|
||||||
我国灵活就业人数超 3 亿
|
|
||||||
345 万
|
|
||||||
热
|
|
||||||
黄仁勋自嘲亚洲家庭关系
|
|
||||||
343 万
|
|
||||||
热
|
|
||||||
香港火灾落案起诉七人及两家公司
|
|
||||||
336 万
|
|
||||||
新
|
|
||||||
重回高考那年还能做对几道
|
|
||||||
329 万
|
|
||||||
热
|
|
||||||
膳魔师致 3 人失明
|
|
||||||
315 万
|
|
||||||
热
|
|
||||||
钉钉副总裁发表长文《置身钉外》
|
|
||||||
315 万
|
|
||||||
热
|
|
||||||
运城多人被臭味熏醒
|
|
||||||
299 万
|
|
||||||
热
|
|
||||||
张桂梅第16次送考
|
|
||||||
294 万
|
|
||||||
广告
|
|
||||||
|
|
||||||
帮助中心
|
|
||||||
服务热线:400-919-0001
|
|
||||||
帮助与客服
|
|
||||||
联系我们
|
|
||||||
更多
|
|
||||||
|
|
||||||
举报中心
|
|
||||||
违法和不良信息举报:010-82716601
|
|
||||||
我的举报
|
|
||||||
更多
|
|
||||||
|
|
||||||
关于知乎
|
|
||||||
知乎个人信息保护指引
|
|
||||||
知乎协议
|
|
||||||
下载知乎
|
|
||||||
Investor Relations
|
|
||||||
网站资质信息
|
|
||||||
更多
|
|
||||||
京ICP证110745号 · 京ICP备13052560号-1 · 京公网安备 11010802020088 号 · 京网文[2025]0422-132 号 · 药品医疗器械网络信息服务备案(京)网药械信息备字(2022)第00334号
|
|
||||||
登录知乎,问答干货一键收藏
|
|
||||||
打开知乎App
|
|
||||||
在「我的页」右上角打开扫一扫
|
|
||||||
其他扫码方式:微信
|
|
||||||
下载知乎App
|
|
||||||
无障碍模式
|
|
||||||
验证码登录密码登录
|
|
||||||
开通机构号
|
|
||||||
中国 +86
|
|
||||||
|
|
||||||
获取短信验证码
|
|
||||||
获取语音验证码
|
|
||||||
登录/注册
|
|
||||||
其他方式登录
|
|
||||||
未注册手机验证后自动登录,注册即代表同意《知乎协议》《隐私保护指引》
|
|
||||||
|
|
||||||
扫码下载知乎 App
|
|
||||||
|
|
||||||
关闭二维码
|
|
||||||
登录即可查看 超5亿 专业优质内容
|
|
||||||
超 5 千万创作者的优质提问、专业回答、深度文章和精彩视频尽在知乎。
|
|
||||||
立即登录/注册
|
|
||||||
Reference in New Issue
Block a user