Unity性能优化分析篇

性能优化是游戏项目开发中一个重要环节。游戏帧率过低,手机发烫, 包体太大,低端机上跑不起来等, 这些都需要来做优化,不管过去,现在,未来,性能优化都是永恒的话题。
而性能优化首先要掌握的是性能分析,通过分析才能发现问题所在。性能分析对于游戏开发是必备的,通过性能分析工具可以给我们提供游戏性能表现的详细信息。如果我们的游戏存在性能问题,如低帧率或者高内存占用,性能分析工具可以帮助我们发现问题的起因,并协助我们解决问题。
 

开始之前,有关性能分析需要了解的概念:

FPS(帧率)

FPS是衡量游戏性能的基本指标。在游戏中,一帧类似于动画中的一帧,FPS是指游戏运行时每秒所运行的帧数,也可以理解为每秒渲染的画面数。
通常FPS越高,表明游戏性能运行越好,对于大多数当前游戏的目标是帧率60FPS,通常来说,帧率在30FPS以上是可以接受的,特别是移动游戏,或者不需要快速反应互动的游戏,对于在VR游戏中,则至少需要90FPS。
实际上FPS并不是衡量游戏稳定体验的理想指标。考虑以下情况:在运行时的前0.75s内渲染了59帧。然后接下来的1帧需要0.25s才能渲染完毕。虽然是60fps,但实际上会让玩家感觉卡顿。对于我们来说更有用的是渲染一帧需要多少毫秒。
渲染一帧,Unity必须执行很多不同的任务。简单的说,Unity必须更新游戏的状态,获取游戏的快照并且把快照画到屏幕上。有一些任务是在每一帧都执行的,包括读取用户输入,执行脚本,运行光照计算等。除此之外,有许多操作是在一帧执行多次的,例如物理运算。当所有这些任务都执行的足够快时,我们的游戏才会有稳定且可接受的帧率。当这些任务执行的不够快时,渲染一帧将花费太长的时间,并且帧率会因此下降。
知道哪些任务花费了太长的时间执行,对于我们怎样去解决性能问题是十分关键的。一旦我们知道了哪些任务降低了帧率,我们就可以尝试去优化游戏的那一部分。这就是为什么性能分析工具这么关键:性能分析工具告诉我们在一帧中每个任务花费了多长时间。


VSync(垂直同步)

VSync将应用程序的帧率与显示器的刷新速率同步。这意味着,如果您有一个60Hz的显示器,并且游戏的帧预算在16.66ms内,则它会强制以60fps运行,而不允许更快。将帧率与显示器的刷新速率同步,可以减轻GPU的负担并解决屏幕撕裂等视觉图像瑕疵。在Unity中,通过Quality settings 可以设置VSync Count (Edit > Project Settings > Quality)。
QualitySettings.vSyncCount有三种选项

  • Don't Sync(不同步) 
  • Every V Blank(每一个垂直同步) 
  • Every Second V Blank(每一秒的垂直同步) 

移动平台忽视 QualitySettings.vSyncCount。仅使用 Application.targetFrameRate 控制帧率。移动平台的最大帧率就是屏幕的刷新率,移动平台上的默认帧率通常为每秒 30 帧。

垂直同步对 FPS 的影响

我们平时用的电脑显示器,一般屏幕的刷新率都是80HZ上下,那么显卡会按照每秒80HZ来发送一个垂直同步信号。

  • 开启垂直同步:显卡绘制完一屏图像后,需要等待80HZ垂直同步信号的到达,才可以开始绘制下一屏。这样游戏自然受到刷新率运行的制约。
  • 关闭垂直同步:那么游戏中显卡绘制完一屏图像后,显卡和显示器无需等待垂直同步信号达到,就可以开始下一屏的绘制,展示了显卡的实力。

但是不要忘记,正是因为垂直同步的存在,才能使得游戏进程和显示器刷新率同步,使得画面更加平滑和稳定。取消了垂直同步信号,固然可以换来更快的速度,但是在图像的连续性上势必打折扣。这也正是很多朋友抱怨关闭垂直后发现画面不连续的理论原因。
 

Unity Profiler

Profiler是Unity内置的强大的性能分析工具,通过Profiler,我们可以了解到cpu使用情况,gpu使用情况,渲染,内存使用情况,声音,物理,网络,UI等等。还可以进行录制数据,分析每帧的运行情况。可以在Unity Editor中进行分析,也可以在目标平台上分析,连接真机,真实了解游戏运行情况。

The CPU usage profiler

当我们查看Profiler窗口的上部时,可以看到完成每帧的任务花费了多少cpu时间。
在CPU usage左侧,可以看到不同颜色的分类块,可以点击显示隐藏你感兴趣的分类,右侧显示各分类的耗时,可以根据颜色块的大小清晰的了解性能的瓶颈所在。最下面可以详细的了解所有任务的耗时,可以精确到各大个函数的耗时,可以根据排序快速定位问题所在,也可以搜索你关心的函数。

渲染分析

渲染是导致性能问题的常见原因。在尝试修复渲染问题前,确定是CPU受限还是GPU受限非常重要,这些情况需要不同的解决方法。 简单来说,CPU负责确定必须绘制什么,GPU负责绘制它。
如果游戏中因为CPU执行渲染任务耗时太久而导致帧渲染时间过长,我们称其为 CPU受限(CPU Bound)。
如果游戏中因为GPU执行渲染任务耗时太久而导致帧渲染时间过长,我们称其为 GPU受限(GPU Bound)。

GPU受限

通过GPU usage快速地判断游戏是否GPU受限。但并非所有设备和驱动程序都支持此分析器。在检查GPU受限之前,需要先检查GPU usage是否适用于我们的目标设备。如果添加GPU usage后有数据意味目标设备支持GPU usage。
如果GPU时间超过CPU时间,可以确定在该点上已经GPU受限。

如果目标硬件不支持GPU usage,仍然可以确定游戏是否GPU受限。可以通过观察CPU使用情况来判断。如果发现CPU正在等待GPU完成其任务,这意味着游戏GPU受限。
如果主线程在Profiler标记(例如Gfx.WaitForPresentOnGfxThread)中花费大量时间,而渲染线程同时显示Gfx.PresentFrame或<GraphicsAPIName>.WaitForLastPresent等标记,则应用程序出现了GPU受限。

CPU受限

如果尚未确定性能问题的原因,我们继续分析基于CPU的渲染问题。

点击选择CPU usage。
在分析器窗口的顶部,CPU usage显示其随时间变化的数据。查看表示渲染的图表中的彩色部分。可以通过在关键字中单击名称旁边的彩色方块来隐藏或显示图表中的数据。
如果一帧中大部分时间由渲染所占用,这表明渲染可能是问题的原因。可以通过以下步骤深入分析数据来确认:
查看分析器窗口底部显示当前选定帧和分析器详细信息的区域。
在该区域左上角的下拉菜单中选择“Hierarchy”。
选择“Time ms”列,按时间(毫秒)对函数进行排序。
单击列表中的顶部函数进行选择。
如果选定的函数是渲染函数,CPU分析器图表将通过Rendering进行突出显示。这种情况意味着与渲染相关的操作导致性能问题,此时游戏处于CPU受限状态。请注意函数名称和执行函数的线程,这些信息将在修复问题时很有用。 

解决GPU受限时的渲染问题

优化填充率
填充率指GPU每秒能够渲染的屏幕像素数量,它是引起GPU的性能问题的最常见因素,尤其是在移动设备上。
填充率相关的优化手段:

  • 优化片元着色器(Fragment Shader)
  • 减少重绘(Overdraw)
  • 优化减少后处理(Image Effects)

优化显存带宽(Memory Bandwidth
显存带宽指GPU对其专用的内存的读写速率。如果游戏出现带宽受限,通常是因为使用了太大的纹理(Texture)。

优化顶点处理(Vertex Processing)
顶点处理指GPU渲染Mesh中的每个顶点使所做的工作。顶点处理的开销与两个因素有关:需要进行渲染的顶点的数量和对每个顶点所要进行的操作。

降低屏幕渲染分辨率,通常这是有效的手段。也可以通过此方法来检验是否GPU受限。

解决CPU受限时的渲染问题

向GPU发送指令的时间开销是引起CPU Bound的最常见原因,向GPU发送指令的过程中,开销最大的操作是SetPass Call。
通常,有3种 降低Batch和SetPass Call数目的方法:

  • 降低需要渲染的对象的数量,可以同时减少Batch和SetPass Call。
  • 降低每个对象需要被渲染的次数,可以减少SetPass Call。
  • 将对象合并到更少的批处理当中,可以减少Batch。

CPU与GPU并不各自孤立:

如果 CPU 在物理计算和脚本运行要花很多时间,那么即使 Shader 优化得再好,也不会提高帧率;
如果 GPU 处理 Shader 消耗大量时间,那么即使优化物理系统和脚本也不会对提高帧率有什么帮助。
当 CPU 压力大,而 GPU 压力小时,就不应该采取一些加大 CPU 压力以减少 GPU 压力的方法。反之亦然。

因此我们要分析找到影响运行性能的短板。

垂直同步的影响

垂直同步(VSync)用来同步游戏的帧率和屏幕的刷新率。垂直同步会影响游戏的帧率,在Profiler窗口中可以看到影响。如果我们不是特别确定问题所在,垂直同步的影响可能看起来像性能问题,我们可以选择在CPU usage profiler中隐藏Vsync信息,也可以在Quality settings 关闭垂直同步。
 

Frame Debugger

Frame Debugger是Unity另一个常用的性能分析工具,它能够让我们详细查看某一帧的渲染过程。只需在菜单栏选择"Window > Analysis > Frame Debugger"即可打开。
在游戏运行中,点击Frame Debugger的Enable按钮,游戏将自动暂停,并在界面中展示当前帧的渲染细节。
界面左侧列表以层级视图形式显示绘制调用(DrawCall、事件等),右侧面板提供有关绘制调用的更多信息,例如几何体细节和用于渲染的着色器。
选中某一渲染步骤后,界面右侧将显示该步骤的详细信息,包括渲染的目标,使用的Shader以及Shader属性等详细信息。同时,Game视图中也会展示该步骤渲染的结果。
Frame Debugger在优化DrawCall和调试Shader时非常有用。

Memory Profiler

Memory Profiler是Unity分析内存性能的进阶工具,可描绘更全面的内存使用情况,使得性能优化与内存问题检测更为方便快捷。您可以使用它来检查Unity应用程序和Unity编辑器的内存使用情况。您可以使用它来捕获、检查和比较内存快照。快照记录了当内存分析器捕获快照时,应用程序使用的内存是如何组织的。Memory Profiler还提供本机和托管内存分配的概述,以评估应用程序的内存使用情况,并识别潜在的问题,如内存泄漏。
要避免应用在容量有限的设备上出现内存溢出崩溃的问题,那么内存优化将是非常关键的一步。此外,如果项目需要发布至多个平台,开发者则需要调整内存占用,以最大化利用每个平台。
Memory Profiler让面临这些挑战的用户能够截取并审查游戏在特定时间点的内存占用。
借助这些“快照”,你可以找出游戏中最占内存的部分或崩溃的原因。

Memory Profiler需要使用Package Manager安装,Package Manager窗口左上角点击“+”,Add pacakge by name : com.unity.memoryprofiler
 

Gmae View Statistics

在Unity的Game视图包括一个统计窗口,显示您的应用程序在运行模式下的实时渲染信息。要打开此窗口,请单击右上角的 Stats 按钮。该窗口会在 Game 视图右上角叠加显示。它包含的统计信息对于优化性能很有用。显示的具体统计信息根据构建目标而有所不同。

Statistics 窗口的字段信息:

  • FPS:当前 Unity 每秒能够绘制的帧数
  • CUP main:处理一帧所花费的总时间。包括 Unity 处理应用程序的帧更新所花费的时间,以及 Unity 在编辑器中更新场景视图、更新其他编辑器窗口或处理仅编辑器任务所花费的时间。
  • CUP render thread:渲染一帧所花费的时间。这个数字包括Unity处理游戏视图的帧更新所花费的时间;它不包括Unity在编辑器中花费的时间。
  • Batches:Unity 在一帧内处理的批次总数。该数字包括静态和动态批次。
  • Saved by batching:    Unity 合并的批次数。为确保良好的批处理,应尽可能在不同游戏对象之间共享材质。更改渲染状态会将批次分成具有相同状态的组。
  • Tris:Unity 在一帧内处理的三角形数。在针对低端硬件进行优化时,这一点非常重要。
  • Verts:Unity 在一帧内处理的顶点数。在针对低端硬件进行优化时,这一点非常重要。
  • Screen:屏幕的分辨率及其使用的内存量。
  • SetPass calls:    Unity 在一帧中切换用于渲染游戏对象的着色器通道的次数。一个着色器可能包含多个着色器通道,每个通道以不同的方式渲染场景中的游戏对象。每个 pass 都需要 Unity 绑定一个新的着色器,这可能会带来 CPU 开销。
  • Shadow casters:在一帧中投射阴影的游戏对象的数量。
  • Visible skinned meshes:Unity 在帧中渲染的带蒙皮的网格渲染器的数量。
  • Animation components playing:帧期间播放的动画数量(Animation)。
  • Animatior components playing:帧期间播放的动画数量(Animatior)。

Scene View Draw Mode

在Unity的Scene视图右上角最左侧,可以改变Scene的绘制模式,不同的绘制模式有时对性能分析也有所帮助。

Shadow Cascades

使用颜色可以采用不同的级联级别显示场景的各个部分。此模式有助于正确设置阴影距离、级联计数和级联分割比率。请注意,此可视化方法会使用通常大于阴影距离的 Scene 视图远平面,因此如果要将摄像机的游戏内行为与小远平面匹配,可能需要缩短阴影距离。

Overdraw

将对象渲染为透明的“轮廓”。透明的颜色会累积,因此可以轻松找到一个对象绘制在另一个对象上的位置。颜色越亮表示Overdraw越高,可以简单的看出哪些地方过渡绘制。
比如在此模式下查看特效,如果发现特别亮,则说明此特效Overdraw过高,应考虑优化。

Mipmaps

使用颜色代码显示理想的纹理大小:红色表示纹理大于必要值(在当前距离和分辨率下) ;蓝色表示纹理可以更大。当然,理想的纹理大小取决于游戏运行的分辨率以及摄像机与特定表面的接近程度。
比如在此模式下浏览场景,如果发现有些地方特别红,则说明这个地方的贴图Mipmap不合理,可以考虑压缩贴图。

Unity是个多平台开发引擎,除了其内置的性能分析工具,也可以通过导出对应的平台工程,使用对应平台原生的性能分析工具,如android studio, xcode

除了在运行时进行性能分析,我们也可以在非运行时对资源进行检测,对性能优化也是十分有帮助的。

UWA本地资源检测

UWA,https://www.uwa4d.com  致力于游戏/VR应用性能诊断与优化,这里主要介绍下它的本地资源检测。

UWA本地资源检测是对游戏、VR等项目工程的资源、代码和设置等进行自动检测的服务,是项目研发持续集成、持续交付流程中的重要一环,旨在为游戏研发制定资源与代码规范,帮助研发团队快速发现和解决项目中的性能问题以及可能出现的异常、错误。研发团队可通过日常的自动检查,规范程序、美术成员的开发,从源头上对项目进行优化,规避风险,节约成本。

到官网下载SDK后,解压放在Editor,即可使用,它有很多类型的检测,每次检测扫描后会生成一份本地数据,需要使用上传工具上传数据到网站后台,然后登陆网站,可以查看分析报告。

详细使用请参考:https://blog.uwa4d.com/archives/UWA_Pipeline40.html

Unity UPR 静态资源检测

Unity UPR,https://upr.unity.cn  是Unity官方的专业团队,为企业用户提供真人真机测试、远程报告诊断、自动化集成以及私有云部署等定制化服务。这里主要介绍下它的静态资源检测
UPR 静态资源检测,不依赖 Unity Editor,通过无需安装的可执行程序,极快速的进行资源扫描。UPR 可以将扫描结果直观的展示出来,帮助开发者尽早发现资源文件中存在的问题。

下载工具后解压,使用assetcheck.exe命令行生成报告数据,可自行上传数据到网站查看报告,也可提前在网站建好项目,工具会自动上传。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/140428.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux C 进程编程

进程编程 进程介绍进程的定义进程和线程以及程序的区别进程块PCB进程的状态相关指令 进程调度算法先来先服务调度算法 FCFS短作业(进程)优先调度算法 SJF优先权调度算法 FPF优先权调度算法的类型非抢占式优先权算法抢占式优先权算法 优先权类型静态优先权动态优先权 高响应比优…

接口测试--知识问答

1 做接口测试当请求参数多时tps下降明显&#xff0c;此接口根据参数从redis中获取数据&#xff0c;每个参数与redis交互一次&#xff0c;当一组参数是tps5133&#xff0c;五组参数是tps1169&#xff0c;多次交互影响了处理性能&#xff0c;请详细阐述如何改进增进效果的方案。 …

酷柚易汛ERP - 序列号状态表操作指南

1、应用场景 序列表状态表统计商品的每个序列号目前的状态&#xff08;在库、已出库&#xff09;&#xff0c;每个序列号仅会显示一条记录。 2、主要操作 打开【仓库】-【序列号状态表】&#xff0c;可勾选序列号在库/已出库两种状态查询&#xff0c;其它筛选操作与上文其它…

垃圾/垃圾桶识别相关开源数据集汇总

垃圾箱图片数据集 数据集下载链接&#xff1a;http://suo.nz/3cvbiC 垃圾箱多类检测数据集 数据集下载链接&#xff1a;http://suo.nz/2eluH3 蒙得维亚的垃圾箱图片 数据集下载链接&#xff1a;http://suo.nz/2lRHLK 垃圾桶满溢检测数据集 数据集下载链接&#xff1a;http:…

【HttpRunner】接口自动化测试框架

简介 2018年python开发者大会上&#xff0c;了解到HttpRuuner开源自动化测试框架&#xff0c;采用YAML/JSON格式管理用例&#xff0c;能录制和转换生成用例功能&#xff0c;充分做到用例与测试代码分离&#xff0c;相比excel维护测试场景数据更加简洁。在此&#xff0c;利用业余…

filte(过滤数组)

根据条件&#xff0c;保留满足条件的对应项&#xff0c;得到一个新数组

关于我在配置zookeeper出现,启动成功,进程存在,但是查看状态却没有出现Mode:xxxxx的问题和我的解决方案

在我输入:zkServer.sh status 之后出现报错码. 报错码&#xff1a; ZooKeeper JMX enabled by default Using config: /opt/software/zookeeper/bin/../conf/zoo.cfgClient port found: 2181. Client address: localhost. Error contacting service. It is probably not runni…

11.读取文件长度-fseek和ftell函数的使用

文章目录 简介1. 写入测试文件2. 读取文件长度 简介 主要讲使用fopen读取文件&#xff0c;配合使用fseek和ftell来读取文件长度。1. 写入测试文件 执行下方程序&#xff0c;使用fwrite函数写入40字节的数据&#xff0c;使其形成文件存入本地目录。#define _CRT_SECURE_NO_WARNI…

【SpringBoot】SpringBoot自动配置底层源码解析

概述 EnableAutoConfiguration源码解析SpringBoot常用条件注解源码解析SpringBoot之Mybatis自动配置源码解析SpringBoot之AOP自动配置源码解析SpringBoot Jar包启动过程源码解析 DeferredImportSelector接口 DeferredImportSelector和ImportSelector的区别在于&#xff1a; …

Leetcode—202.快乐数【简单】

2023每日刷题&#xff08;二十八&#xff09; Leetcode—202.快乐数 快慢指针思想 通过手玩2&#xff0c;可以发现 会走入一个循环&#xff0c;并且fast和slow会在一个数字相遇&#xff0c;以下也大概花了一下推倒出来了。如果slow不是因为1和fast相等的&#xff0c;就说明它…

Nginx的安装

Nginx的安装 Windows下Nginx的安装 1、下载nginx 下载稳定版本: http://nginx.org/en/download.html 直接下载 nginx-1.20.0.zip : http://nginx.org/download/nginx-1.20.0.zip 下载后解压&#xff0c;解压后如下&#xff1a; 2、启动Nginx 有很多种方法启动nginx (…

如何准确分析需求

业务驱动的需求思想 要做好软件需求工作&#xff0c;业务驱动需求思想是核心。传统的需求分析是站在技术视角展开的&#xff0c;关注的是“方案级需求”&#xff1b;而业务驱动的需求思想则是站在用户视角展开的&#xff0c;关注的是“问题级需求”。 变更/优化型需求分析任务…

视频监控系统EasyCVR平台播放告警录像时,播放器显示不全是什么原因?

防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防…

Python高级语法----Python类型注解与类型检查

文章目录 一、类型注解基础二、使用 `mypy` 进行类型检查三、类型注解的最佳实践结论在当今的软件开发实践中,类型注解和类型检查在提高代码的可读性和健壮性方面发挥着至关重要的作用。尤其在 Python 这种动态类型语言中,通过类型注解和类型检查工具,如 mypy,可以显著提升…

Git系列之分支与标签的使用及应用场景模拟

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《Git实战开发》。&#x1f3af;&#x1f3af; &a…

语音识别芯片在产品应用上的难点列举

语音识别技术&#xff0c;作为人工智能领域中的一颗璀璨明珠&#xff0c;已经广泛应用于用户交互、智能家居、语音助手等多个领域。它为我们的生活带来了诸多便利&#xff0c;使得我们可以更加高效地与电子设备进行互动。然而&#xff0c;语音识别技术的实现&#xff0c;依赖于…

LEEDCODE 75颜色分类

耍赖皮写法 嘻嘻 class Solution { public:void sortColors(vector<int>& nums) {int count1 0;int count2 0;int count3 0;for(int i 0; i<nums.size(); i){if(nums[i] 0)count1 1;else if(nums[i] 1)count2 1;else count3 1;}for(int i 0; i<nu…

缅因州政府通知130万人MOVEit数据泄露事件

大家好&#xff0c;今天我要向大家通报一个令人震惊的消息&#xff1a;缅因州政府的系统遭到了入侵&#xff0c;黑客利用MOVEit文件传输工具的漏洞&#xff0c;获取了约130万人的个人信息&#xff0c;这几乎相当于该州的整个人口数量。 MOVEit攻击是Clop勒索软件团伙进行的一次…

前端---CSS的盒模型

文章目录 什么是盒模型&#xff1f;设置边框设置内边距设置外边距块级元素水平居中 什么是盒模型&#xff1f; 页面上的每个HTML元素都是一个一个的“盒子”&#xff0c;这些盒子由&#xff1a;内容、内边距、边框、外边距组成。 我们可以和住的房子联系起来&#xff0c;更好…