客户端性能测试基础知识
目录
1、客户端性能
1.1、客户端性能基础知识
2、客户端性能工具介绍与环境搭建
2.1.1、perfdog的使用
2.1.2、renderdoc的使用
1、客户端性能
1.1、客户端性能基础知识
客户端性能知识这里对2D和3D类游戏进行展开进行,讲述的有内存、CPU、GPU、帧率这几个模块内容。其中不管是2D还是3D类游戏,都一定会包含有图片、字体、音频这些资源。2D类游戏主要的资源是图片,所以对于渲染这块的内容核心在于CPU的draw call方面;而3D类游戏包含的资源很多,有模型、物理组件、光影效果、网格、shader、材质纹理等内容,所以3D类游戏在渲染这块的内容核心包括CPU的draw call以及GPU的渲染计算方面。下面分别对影响内存、CPU、GPU性能方面进行讲解。
影响内存的因素
对于一款游戏,基本的可以分为脚本和资源两部分,而脚本通常会包括代码和导表数据。对于代码中,没有及时回收的无用变量,会占用了内存空间,慢慢积累后也就是成了我们所说的内存泄漏。导表数据也是一个我们需要关注的点,游戏里面有某些表格往往会比较大,有的甚至达到几M的数据,而在一个场景中,可能要加载多个表格的数据,这就需要将这些需要用到的表格都加载进入到内存当中,但是实际上,当前场景所有到的数据往往仅是数据表格的一小部分数据而已,这就导致了有大量的表格数据在内存中是无用的,但是又必须要加载进去。所以,表格数据的优化也是一个比较重要的内容之一,常规的表格优化策略有:
- 通过功能数据放在独立的表格
- 去除表格中未被使用的冗余字段
- 对数据量大的表格进行分块处理,使用中间文件做索引,做到分块导表,按需加载
而对于资源内容,通用的资源有字体、音频、UI、纹理图片,这通用资源里面其实已经包含了2D的了,因为2D的资源也就是以上的这些内容。而3D的则还有网格、材质、着色器这些内容。下面针对这些影响因素逐个介绍。
字体,一款游戏中使用到的字体往往有多种,而一个字体小的有几兆,大的甚至十几兆,而游戏中加载字体都是全部加载进去且大部分是常驻内存的,并且游戏在开发期时,可能使用了多款字体,但是实际上游戏中使用的没有么多,导致字体在内存中占用了许多的内存。所以针对这点,我这里也拿出来提及一下,因为字体的加载大小几乎等同于字体实际的大小,可以说是冗余的字体和多种字体既占包体量也占内存。
音频,游戏音频也是会对内存造成一定的占用的,这点也同样需要在性能测试过程需要考虑的。游戏里面常用的音频有ogg格式的,mp3格式的,wav格式的以及wwise音频引擎的使用bnk格式作为音频资源。对于游戏音频,一种常规的优化策略是:
- 对于长时间的音乐,建议采用压缩格式的mp3
- 对于短时间的音效,建议采用非压缩给是wav
对于unity里面的音效设置,刚开始的音源文件可能是1.4Mb,如果采用的格式是加载时解压缩,那么最后的音源在内存中的大小将高达10.2Mb。所以音源的加载策略也是一个很重要的影响因素。一般的加载方式有加载时解压缩、压缩内存、流式处理。这几种方式各有优缺点,无非就是在速度与内存空间两个方面的取舍程度,需要项目里面根据实际的需求选择合适自己项目的方式,这里我就不给建议了。
UI,游戏UI界面往往容易造成的性能问题是卡顿、界面打开慢等,导致UI的过度绘制。在游戏中,UI的销毁处理一般有三种情况,一种是关闭UI后立即销毁,不做任何的缓存;一种是第一次打开UI后,对UI先进行缓存处理,关闭UI后,不销毁UI,下次打开速度快,等到切换场景时才销毁;第三种是关闭UI后,不销毁UI,直到内存达到预警值时再进行销毁;对于我们测试来说,需要了解UI在内存的处理方式后,还需要关注该种模式下是否存在掉帧、卡顿的情况,是否出现内存泄漏的情况。如果有,那么我们需要定位出来是那些UI导致的掉帧、卡顿或者内存泄漏。常规的做法有:
- 叫程序在客户端打印每个场景界面的UI列表log,列出UI的 名字、尺寸、大小,测试人员可以收集前后的UI数据定位出问题所在
- 使用renderdoc查看某界面的资源加载情况,确认哪个资源,那一帧导致的掉帧、卡顿问题,renderdoc的使用方法请参考:renderdoc的使用
- 使用prefdog等工具查看内存是否存在泄漏情况,并确认是否是UI重复打开关闭导致的
纹理图片,纹理对于内存的消耗是巨大的,一个2048*2048的纹理,采用32为颜色深度编码的话,将消耗16M的内存,一个1024*1024的纹理也需要消耗4M的内存(大体计算方式:(大小)*(编码位数/8),即1024*1024*(32/8)byte =1024*4kb = 4Mb。
以上场景的纹理贴图中2048*2048规格的的图片占用内容会比较大,这些纹理贴图需要美术优化。
需确认纹理在512*512、1024*1024、2048*2048几种大小以及在dds、tga两种格式下的内存占用情况,目标如下:
纹理的处理可以经过压缩,不过压缩后,效果可能不是很理想。一种做法是在原图的基础上,将纹理的长宽分辨率比例放大一倍,然后在保持原有的压缩格式,这样压缩出来的结果还是要比原图要小一些。另外一种处理就是进行高低配分级处理,先设置好分级,针对中低档设备则进行纹理压缩,针对高端档设备,可以保持不压缩纹理。
3D类游戏的资源
网格,需要能够确定出场景模型的网格占用情况,对于unity3D类的模型中,有些模型没有勾选【Rig】下的Optimize GameObject(优化游戏对象)选项,这个选项可以把SceneManager中用于Skinning的节点都去掉,从而节省场景节点树更新以及查询的CPU消耗。
与此同时,网格文件Mesh里面会包含有大量的color数据,normal数据,tangent数据。这些数据也会对内存占用比较大。
材质贴图,3D的材质贴图主要是纹理贴图,纹理贴图中我们需要关注的有纹理格式,纹理的尺寸、mipmap功能,勾选了read&write功能等。这些都会影响到游戏内存的。
对于纹理格式,需要设备硬件支持,不过目前为止基本大部分设备都支持了各种格式的纹理了,不过可能还会遇到如下的两个问题:
纹理的尺寸问题,纹理的大小的计算和上面贴图所示的估算公式一致。
纹理的mipmap和read&write功能可以在unity中的纹理属性中看到是否有勾选。一般情况下模型的mipmap建议勾选,这对提高渲染效率,尽管勾选后,内存会增加1.33倍,但是渲染效率大大提高,还是值得的,但是UI的纹理建议不要勾选了,UI本身就渲染在屏幕上,渲染提高不大,反而会增加了内存;然后read&write选项建议不要勾选。
着色器(shader),shader作为能增强炫丽的渲染效果的脚本,很多时候程序、TA为了增强效果,加了好多shader,这个可能会对内存有较大的开销。如下图是我自制的一个很小的单场景demo下shader所占用的内存空间就多大5.1Mb了。那在一款成型的3D类游戏中,可能会有更多的shader内存了。
对于内存影响因素的内容这里就讲述上述的这几个,当然还是有其他的影响因素,但是相对没那么重要的,核心的或者说常规的就是上面的这些因素,如需了解其他的因素的话,请自行去搜索学习,下面讲CPU的性能影响因素。
影响CPU性能的因素
游戏中影响CPU性能除了本身游戏逻辑代码处理之外,CPU对于渲染指令的处理也是影响其性能的主要原因之一。主要就是这两块影响的,对于逻辑代码这块,主要就是编程规范和算法设计的不合理导致CPU出现性能压力。同时CPU在对图形渲染这块的处理也是常常会出现性能瓶颈问题的。在渲染这块中,draw call调用、Batches批次、UI调用、物理组件的处理以及GC调用都是比较影响CPU性能的,所以这四块的内容优化会直接影响到CPU的性能。所以这里也主要针对这四块进行说明。
Draw call
Draw call是CPU对底层图形接口的调用,是CPU提交数据 、指令、状态等内容给GPU的时候调用的,但由于GPU的计算速度往往比CPU调用draw call的快,如果CPU出现负载,那么会造成卡顿掉帧。优化的做法就是对同类资源进行合批渲染,静态资源看看能否进行合批,从而较少draw call次数。一般建议的draw call在100以内。
Draw call可以的查看可以在unity的性能分析器里面看,程序那边一般也都会在游戏中指令打印出来的,也可以通过指令查看。
Batches批次是合批,合批有静态合批与动态合批,合批的目的是减少draw call的调用,从而降低CPU的性能压力。静态合批是手动设置的,1、通过设置游戏中需要合批的模型资源,然后在游戏导出时,在Player setting里面设置static batching,这样设置后导出时unity就好帮我们合批了,不过这样会增大包体大小,但是会运行快一些;2、在unity里面直接勾选static属性,这样设置时,物体是在加载过程才进行合批,这样包体会更小,但是运行会慢一些,内存也会相应增大。动态合批是unity引擎自动帮我们合批的,我们可以不用理会。不过动态合批有许多的限制:
- 动态合批处理的物体顶点数量不超过900个,包括shader里面的顶点设置
- 如果GameObjects在Transform上包含镜像,则不会对其进行动态合批处理
- 使用不同的Material实例会导致GameObjects不能一起批处理,即使它们基本相同
- 带有光照贴图的GameObjects有额外的渲染器参数:保存光照贴图的索引和偏移/缩放。一般来说,动态光照贴图的GameObjects应指向完全相同的光照贴图位置才能被动态合批处理
静态合批有渲染上的优点,但是也有缺点,就是合批后,在运行过程中会增加内存的消耗,所以对于CPU与内存间的优化需要衡量两者间的短板所在,择优而选,而不能一昧的追求极端,反而会影响到了其他方面的性能。
在Unity中的Frame Debugger也可以抓帧查看详细的渲染与合批过程,在unity中,因为有Batch的存在,在一个Batch批次中,可能会有出现合批了几十个甚至上百个Draw Call。也就是说,Unity的Batch并不能实际减少Draw Call的数量,但是合批次后性能会有较大的提升。原因是Batch合批次后,尽管没有降低Draw Call的数量,但是会将能够合批次的数据一次性提交了,这样Draw Call里面的大头的数据被抽出来一次提交了,剩余的Draw Call在CPU提交的时候带宽压力就会小很多。大致可以理解为假设一个Draw Call是一个1K大小的文件,合批时将1千个1K大小文件里面90%大小的数据一次性提交了,剩余的文件数量经过不变,但是每个文件的数据量被抽减到了只剩下10%的数据,也就是说处理器原本需要处理的1K大小的文件,变成了只需要处理0.1K大小的数据,压力自然就提升了。
UI调用也挺会增加CPU的负担的,不合理的UI布局和调用会导致CPU过渡绘制和调用,增加CPU性能压力。一般的优化策略有
- 同一个UI界面的图片尽量合到一张图集里面去,减少draw call
- 通用的图片放到一张共享图集里面去
- 不同格式的图片放到不同的图集
- 减少图片的尺寸
- 合理使用UI层级,在一个UI工程里面,尽量不要使用复杂的UI结构
- 动态UI与静态UI进行分离,减少不必要的绘制
- 透明UI要慎用,可能会增加重绘
物理组件,物理组件的大量使用也会增加CPU的计算压力,对于物理组件的优化策略有:
- 尽量不使用网格碰撞器
- 选择使用合适的Fixed Timestep
这个设置在edit-项目设置-时间-固定的时间步进里面设置,默认是0.02s,也就是20ms。
GC调用,尽管GC是用来处理优化内存的,但是频繁的调用也是会增加CPU的逻辑处理开销,因此对于CPU的优化,那么减少GC的调用触发也是一个操作。
GC被触发的条件有:
- 堆内存不足,自动触发GC调用
- 程序手动调用GC
问题一般会出现在程序手动频繁调用GC,同时也是一些编程不够规范引发了垃圾数据,是的系统堆内存过低而触发GC。
影响GPU性能的因素
对GPU性能的影响主要体现在渲染方面的压力,导致的结果有游戏掉帧、耗电量过高等表现。我们可以大致了知道GPU的功能就是计算,那么影响到GPU计算效率的无非就是两大方面:一是面数过多,像素计算复杂;另一个是GPU显存带宽。
所以针对上面的这两点,就可以有对应的优化策略。主要的优化策略有:
- 减少顶点数量
- 纹理图片尺寸不易过大
- 使用LOD技术
- 使用遮挡剔除
- 使用合图图集
- 大场景使用烘焙光影替代BPR光影
- 移动端类游戏,使用mobile版的shader
- UI元素不使用mipmap设置(合理使用mipmap)
对于客户端性能的基础知识这里就可以讲这么多,当然还有unity性能管线、Shader、纹理等方面的内容,由于时间关系这里先不写了。
后面有空再写一篇关于如何定位、优化性能问题。
2、客户端性能工具介绍与环境搭建
2.1.1、perfdog的使用
腾讯旗下的perfdog可以用于检测客户端帧率、CPU甚至GPU等数据情况,关于perfdog的使用请参考官网说明:https://perfdog.qq.com/
这里可以讲一下关于perfdog的用例设计,我给出几点总结:
- 用例设计时,尽量保持单一变量,从而使得检测数据更具有说服力
- 测试过程,每个步骤尽量在ferfdog中的timeline(时间轴)上面的tag编写清除,便于对比与定位问题
- 收集录制的文件命名尽量用下划线拼接,便于阅读,如:小米6x_主线
2.1.2、renderdoc的使用
Renderdoc这个工具可以抓帧定位资源渲染加载过程的问题,同时也可以找出被抓取的界面的的资源名字与大小,用于定位一些资源、渲染速度、加载过程的性能问题。关于renderdoc的使用,请参考附件;
1.3客户端性能测试点
客户端性能的测试点,不同项目功能不一样,不过可以抛砖引玉的给出一些思路,如下图所示给出一些常规的测试过程的几种情况。当然,具体的用例设计还是要在围绕下面的几种情况的同时,针对具体的功能进行细化。
相关文章:

客户端性能测试基础知识
目录 1、客户端性能 1.1、客户端性能基础知识 2、客户端性能工具介绍与环境搭建 2.1.1、perfdog的使用 2.1.2、renderdoc的使用 1、客户端性能 1.1、客户端性能基础知识 客户端性能知识这里对2D和3D类游戏进行展开进行,讲述的有内存、CPU、GPU、帧率这几个模块…...

多模态论文阅读之VLMo
VLMo泛读 TitleMotivationContributionModelExpertimentsSummary Title VLMo:Unified Vision_Langugae Pre-Training with Mixture-of-Modality-Experts Motivation CLIP和ALIGN都采用dual-encoder的方式分别编码图像和文本,模态之间的交互采用cosine similarity…...

休闲类手游还有机会吗?两大策略收割全球玩家
刚刚过去的第三季度,是全球手游市场逆势增长的高光时刻。 买量、营收、下载等多项数据表现优异,其中买量最为突出的产品是休闲类游戏,广告主数占比23.76%断层第一,广告素材占比17.62%,是当之无愧的“广告顶流”。 数…...

Git复制代码
目录 一、常用下载代码 1.登录Git克隆SSH编辑 2.新建文件然后右键点击Git Bash Here 3.git clone Paste 二. 本地下载 1.从本地进入页面 2.生成代码——>导入——>生成代码后下载 3.解压道相应位置 一、常用下载代码 1.登录Git克隆SSH 2.新建文件然后右键点击…...

数据结构笔记——查找、排序(王道408)
文章目录 查找基本概念线性表查找顺序查找折半查找(二分)分块查找 树查找二叉排序树(BST)平衡二叉树(AVL)的插入平衡化复杂度分析 平衡二叉树的删除 红黑树红黑树的定义和性质红黑树定义红黑树性质 红黑树的…...

MySQL---搜索引擎
MySQL的存储引擎是什么 MySQL当中数据用各种不同的技术存储在文件中,每一种技术都使用不同的存储机制,索引技巧 锁定水平,以及最终提供的不同的功能和能力,这些就是我们说的存储引擎。 MySQL存储引擎的功能 1.MySQL将数据存储在文…...

2022最新版-李宏毅机器学习深度学习课程-P32 Transformer
一、 seq2seq 1. 含义 输入一个序列,机器输出另一个序列,输出序列长度由机器决定。 文本翻译:文本至文本; 语音识别:语音至文本; 语音合成:文本至语音; 聊天机器人&#…...

如何使用商品详情API接口获取商品数据:一篇详尽的论述
一、引言 商品详情API接口是一种用于获取商品详细信息的应用程序接口。通过调用该接口,我们可以获取商品的名称、价格、描述、图片以及其他相关属性。对于电商平台、价格比较网站、数据分析等应用场景来说,商品详情API接口提供了便捷的数据获取方式。本…...

华为:手机王者归来,汽车起死回生
作为一家全球知名的科技公司,华为在通信、智能手机、平板电脑等领域拥有很高的市场份额和品牌影响力。而随着华为开始进军汽车领域,通过自主研发和合作,不断提升自己在汽车领域的竞争力,华为便也开始受到更为广泛的关注。 只不过…...

Vue3.0 provide与inject依赖注入:VCA
简介 provide 与 inject 是一种跨层级组件(祖孙)通信方式。当组件多层嵌套时,不需要将数据一层一层的向下传递,通过它俩可以实现跨层级组件通信。 provide:提供者 注入一个值,可以被后代组件接收。 prov…...

前端react入门day02-React中的事件绑定与组件
(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 React中的事件绑定 React 基础事件绑定 使用事件对象参数 传递自定义参数 同时传递事件对象和自定义参…...

工业5G路由器;小体积 千兆高速通信组网
计讯物联工业路由器TR232,5G高速网络,超低时延、高可靠性,小体积、易安装、强兼容,串口/网口多设备接入联网,为用户提供高速稳定的数据传输通道 。 小体积5G工业路由器TR323,外形1047824mm࿰…...

【深度学习基础】从R-CNN到Fast R-CNN,再到MaskR-CNN,发展历程讲清楚!
📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…...

面试算法51:节点值之和最大的路径
题目 在二叉树中将路径定义为顺着节点之间的连接从任意一个节点开始到达任意一个节点所经过的所有节点。路径中至少包含一个节点,不一定经过二叉树的根节点,也不一定经过叶节点。给定非空的一棵二叉树,请求出二叉树所有路径上节点值之和的最…...

阿里云 k8s 容器服务 设置节点为不可调度的两种方法有什么区别?
两种方法的区别在于:drain 会驱逐原来节点上的所有 pod,而 cordon 只是停止调度, 禁止新的 pod 调度进来,但旧的 pod 不会受影响。...

新一代数据质量平台datavines
在我实习的第一家公司的时候,有幸参与Apache Griffin的开发,也先后在一起其他公司使用过数据质量平台,同时也调研过一些开源的数据质量平台。 最近和朋友一起参与开发了datavines数据质量平台,随着在数据行业越呆越久,…...

建议收藏《2023华为海思实习笔试-数字芯片真题+解析》(附下载)
华为海思一直以来是从业者想要进入的热门公司。但是岗位就那么多,在面试的时候,很多同学因为准备不充分,与岗位失之交臂,无缘进入该公司。今天为大家带来《2023华为海思实习笔试-数字芯片真题解析》题目来源于众多网友对笔试的记录…...

【详细教程】关于如何使用GitGitHub的基本操作汇总GitHub的密钥配置 ->(个人学习记录笔记)
文章目录 1. Git使用篇1.1 下载安装Git1.2 使用Git 2. GitHub使用篇2.1 如何git与GitHub建立联系呢?2.2 配置公钥 1. Git使用篇 1.1 下载安装Git 点击 官网链接 后,进入Git官网,下载安装包 然后根据系统类型进行下载,一般为wind…...

HTML样式CSS、图像
HTML样式-CSS: CSS (Cascading Style Sheets) 用于渲染HTML元素标签的样式。CSS可以通过以下方式添加到HTML中:1)、内联方式:在HTML元素中使用“style”属性;2)、内部样式表:在HTML文档头部<head>区…...

智能电表瞬时电量是什么意思?
智能电表已经成为我们进行能源管理的重要工具。其中,瞬时电量这一概念逐渐走进大众视野。那么,智能电表瞬时电量究竟是什么意思?它对我们的生活和能源管理又有哪些影响呢?下面,小编就来为大家介绍一下瞬时电量…...

Redis之 redis.config配置文件
文章目录 前言一、基本配置1.单位2.包含3.网络配置4.通用5.快照6.安全7.限制8.仅追加模式 二、总体主要介绍总结 前言 行家一出手,就知有没有,让一起学习redis.config配置文件。 一、基本配置 Redis 的配置文件位于 Redis 安装目录下,文件名…...

BIOS开发笔记 - CMOS
CMOS原来指的是一种生产电子电路的工艺,在PC上一般指的是RTC电路单元,因为早期它是由这种工艺生产出来的,所以又把RTC称作了CMOS。 RTC(Real Time Clock)即实时时钟,用于保存记录时间和日期,也可以用来做定时开机功能。RTC靠一组独立的电源给它供电,这样设计的目的就是…...

leetcode_117 填充每个节点的下一个右侧节点指针 II
文章目录 1. 题意2. 题解2.1 BFS2.2 BFS空间优化2.3 DFS序层次记录 3. Ref 1. 题意 在一颗树的同层之间用指针把他们链接起来。 填充每个节点的下一个右侧节点指针 II 2. 题解 2.1 BFS 用一个变量记录下同层最右侧的节点,当遍历到时更新下一层的最右侧节点即可…...

亲测 IDEA Pycharm 全家桶 自动重置免费30天
理论上是通用的 插件市场安装 添加第三方插件仓库地址 在Settings/Preferences... -> Plugins 内手动添加第三方插件仓库地址:https://plugins.zhile.io 搜索:IDE Eval Reset插件进行安装。如果搜索不到请注意是否做好了上一步?网络是否…...

Marp: 将 Markdown 变为 PPT 式样的 VScode 插件
样例代码: --- marp: true size: 16:9 theme: default header: footer: --- <!-- _footer: Jia ming<br>Gansu University of Political Science and Law --> <!-- _backgroundColor: lightskyblue --> ## <!-- fit --> 笔记检验概述>…...

根据正则表达式截取字串符,这个办法打败99%程序员
作为一名程序员,常常会在以下情况下使用函数功能根据正则表达式截取字符串: 1.字符串处理:当需要使用正则表达式匹配和提取字符串中的特定模式时,可以使用该函数。例如,从一段文本中提取电子邮件地址、电话号码或网站…...

冬天女儿的羽绒服就选它了,哈哈很喜欢
长款设计感满满的羽绒服 真的一下子就戳中了我的心巴 90白鸭绒+杜邦三防工艺+精细压线 厚实保暖不臃肿,粉色撞色甜美又可爱...

Vim插件配置
工欲善其事,必先利其器,倒腾一下vim的配置,做个记录。 ".vimrc里的内容:""for base configure set t_Co256 if ! has("gui_running")set t_Co256 endifif &diffhighlight DiffAdd ctermbold cte…...

函数参数的最佳传递方式与现代C++的规则
函数参数的最佳传递方式与现代C的规则 在C中,如何最佳地传递函数参数以及如何处理类的特殊成员函数,一直是优化性能和代码质量的重要话题。下面我将详细解释这些概念。 使用移动语义实现 Swap 函数 移动语义(Move Semantics)能…...

Asterisk Ubuntu 安装
更新环境 sudo apt update sudo apt install wget build-essential git autoconf subversion pkg-config libtool sudo contrib/scripts/get_mp3_source.sh A addons/mp3 A addons/mp3/common.c A addons/mp3/huffman.h A addons/mp3/tabinit.c A addons/mp3/Ma…...