游戏开发58课 性能优化

news2024/11/30 0:48:41

6. 卡顿优化

相信很多研发者或玩家,都遇到这种情况:游戏大部时间运行都很流畅,但在战斗的某些时刻或者打开某些界面会卡一下,甚至卡很久。这个现象就是卡顿。引发卡顿的原因有很多,但主要有:

  • 突发大量IO。
  • 短时大量内存操作。
  • 渲染物体突然暴涨。
  • 触发GC。
  • 加载资源量多的场景或界面。
  • 触发过多过复杂的逻辑。

避免或者缓解卡顿的技法也是围绕以上原因展开。

6.1 降帧法

跟3.3的方法类似,通过强制降低更新频率,减缓卡顿的时间。

6.2 摊帧法

摊帧法就是本来需要在同一帧处理的逻辑分为若干份,分摊到若干帧去处理,从而缓解同一帧的处理时间,减缓卡顿现象。例如,本来在同一帧需要创建10个小兵,这个很可能会引发卡顿,那么可以每帧只创建2个,分摊到5帧创建完。适用此法的还有资源的加载,AI的更新,物理的更新,耗时逻辑的处理等等。此外,还可以用预处理(3.2),主次法(3.4)来避免卡顿。

6.3 限制数量法

如果降帧法,摊帧法,预处理,主次法都无法解决现象,卡顿原因又刚好是因为物体数量过多,那么限制数量就非常有必要了。做法就非常简单,当场景内创建某种物体(角色,特效,血条等)的数量到底最大值时,便强制不再创建。此法可能会引起逻辑的一些错误和不好的游戏体验,需谨慎使用和处理。

6.4 逻辑优化

如果卡顿是逻辑过于复杂引起的,就需要针对性地优化逻辑。每个项目的逻辑不一样,这里无法给出具体的优化措施。

6.5 IO优化

因IO慢引起主线程等待,从而导致游戏卡顿的现象非常普遍,下面有一些常用的优化技法。

6.5.1 预加载

将耗时的IO提前到某个时刻(游戏启动时,场景加载时,进入主界面时等)加载,比如有些角色资源大,可以在加载战斗场景时提前加载,以免战斗过程中卡顿。

6.5.2 异步加载

将IO异步化,以避免卡主线程。此技法应用非常普遍了,不再累述。

6.5.3 压缩资源

将本来零散的文件压缩成单个文件,或者对大文件利用一定算法(如哈夫曼编码)压缩,减少文件大小。这样也可以降低IO时间。当然,压缩资源也有副作用,需占用多一份内存,解压缩过程也要耗费额外的CPU。

6.5.4 多级缓存

我们都知道CPU的频率是最高的,目前家用PC的主频可达3.2GHz甚至更高,CPU内有L1L3缓存,它们速度略有差别;内存的存取速度远低于CPU,一般是23GHz,约是CPU的1/10。硬盘存取速度又远低于内存,普遍是0.1Gb/s,远低于内存读取速度。而网络更慢,目前即便是光纤,也不过0.02Gb/s。通常我们能操控的是内存/磁盘和网络的数据,所以只要关注它们的速度,它们的速度关系大致如下图。

所以,多级缓存策略应运而生。做法跟缓存法类似,只是多了层磁盘缓存,实现伪代码:

map<string, ObjectType> _memoryCache;

ObjectType CreateObject(string objectPath)
{
    // 1. 先尝试从内存缓存中读取,有就直接返回。
    if (_memoryCache.count(objectPath) > 0)
    {
        return _memoryCache[objectPath];
    }

    ObjectType obj = NULL;
    // 2. 再尝试从磁盘加载。
    if (FileExisted(objectPath))
    {
        obj = LoadObjectFromFile(objectPath);
        _memoryCache[objectPath] = obj;
        return obj;
    }
    
    // 3. 最后才从网络下载
    DownloadObjectFromNet(objectPath);
    obj = LoadObjectFromFile(objectPath);
    _memoryCache[objectPath] = obj;
    return obj;
}

6.5.5 控制Log

游戏的Log通常会隔一段时间存档,如果逻辑处理不好,很可能引发卡顿。比如,每帧输出大量调试log,会引发频繁存档。游戏Z在早期,也曾发生卡顿现象,后来经Profiler分析发现是Log存档引发的。所以,有必要对Log做出一些优化。常见的优化方法:

  • 避免帧更新输出Log。防止Log数据迅速膨胀引起频繁存档或增加存档时间。
  • 改进Log存档机制。可以适当改进Log存档机制,比如每隔多少时间存档一次,或者Log数据到达一定量级触发。
  • 建立Log等级。可以将Log分为Info,Warning,Error几个级别,不重要的log不存档。
  • 异步存档。将存档Log的逻辑防止单独的线程,防止卡主线程。
  • 避免无用的log。这就要在逻辑层控制log输出,避免无效的log。

6.5.6 JSON代替XML

游戏数据存储一般有两种:二进制和文本格式。二进制格式数据量最小,但可读性和扩展性差,适合存储模型/纹理/字体/音频等数据。文本格式的特点跟二进制刚好相反,适合存储配置信息。最常见的文本格式有JSON和XML两种,其中JSON对比XML有诸多优点:

  • 数据量少。表达同样的数据,JSON格式可以比XML少40%(见下)。
<?xml version="1.0" encoding="utf-8" ?>
<country>
  <name>中国</name>
  <province>
    <name>福建</name>
    <citys>
      <city>福州</city>
      <city>南平</city>
    </citys>    
  </province>
  <province>
    <name>广东</name>
    <citys>
      <city>广州</city>
      <city>深圳</city>
      <city>梅州</city>
    </citys>   
  </province>
</country>
{
    name: "中国",
    provinces: [
      { name: "福建", citys: { city: ["福州", "南平"]} },
      { name: "广东", citys: { city: ["广州", "深圳", "梅州"]} }
    ]
}
  • 可读性更佳。上面两段分别是XML和JSON表达相同的数据,谁可读性更佳一目了然。
  • 更快的解析。JSON因为数据量更小,IO也会更快,解析速度当然也更快。

每个游戏都有大量逻辑数据需要存档,比如角色信息,技能信息,场景信息,配置信息等等。这些数据如果适合用文本格式存储,首选JSON无疑。

6.6 使用进度条

如果上面那些章节都无法解决卡顿现象,可以尝试使用进度条。思路是将卡顿逻辑抽离出来,分成若干阶段(step),每完成一个step,给一帧时间刷新UI进度条。当然也可以用异步方式实现。伪代码:

HandleStep1();
RefreshProgressBar(1 / n);
WaitForNextFrame();

HandleStep2();
RefreshProgressBar(2 / n);
WaitForNextFrame();

...

HandleStepN();
RefreshProgressBar(1);
WaitForNextFrame();

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

银河麒麟桌面V10SP1版本系统休眠唤醒鼠标键盘失效解决方法

使用银河麒麟桌面系统有时会出现系统休眠后再唤醒&#xff0c;鼠标键盘失效的问题&#xff0c;可尝试以下方法解决。 1.检查是否安装 laptop-mode-tools 工具 执行命令: dpkg -l | grep laptop-mode-tools如果执行命令无结果输出&#xff0c;表示未安装(如果已安装&#xff0…

【从零开始学习深度学习】21. 卷积神经网络(CNN)之二维卷积层原理介绍、如何用卷积层检测物体边缘

目录1. 二维互相关运算2. 自定义二维卷积层3. 卷积层的应用----图像中物体边缘检测4. 通过数据学习核数组5. 互相关运算和卷积运算6. 特征图和感受野总结卷积神经网络&#xff08;convolutional neural network&#xff09;是含有卷积层&#xff08;convolutional layer&#x…

欧克科技在深交所上市:客户集中度较高,胡坚晟为控股股东

12月12日&#xff0c;欧克科技股份有限公司&#xff08;下称“欧克科技”&#xff0c;SZ:001223&#xff09;在深圳证券交易所主板上市。本次上市&#xff0c;欧克科技的发行价格为65.58元/股&#xff0c;发行数量为1668万股&#xff0c;募资总额约为10.94亿元&#xff0c;募资…

印制电路板(PCB)设计原则和抗干扰措施

印制电路板(PCB)是电子产品中电路元件和器件的支撑件&#xff0e;它提供电路元件和器件之间的电气连接。随着电于技术的飞速发展&#xff0c;PCB的密度越来越高。PCB 设计的好坏对抗干扰能力影响很大&#xff0c;因此&#xff0c;在进行PCB 设计时&#xff0e;必须遵守PCB设计的…

Nginx 防盗链

Nginx 防盗链 本篇主要介绍一下 nginx 中 防盗链的具体配置 , 以及http 的 referer 头 概述 防盗链其实就是 防止别的站点来引用你的 资源, 占用你的流量 在了解nginx 防盗链之前 我们先了解一下 什么是 HTTP 的头信息 Referer,当浏览器访问网站的时候,一般会带上Referer,告…

【TS】TypeScript声明文件(.d.ts)的使用

前言 当我们在TS文件中需要引入外部库时&#xff0c;编译时是无法判断传入参数的类型的&#xff0c;所以我们需要在引入前加入一个声明文件来帮助ts判断类型。 当然现在大部分库都自带有自己的声明文件&#xff0c;一般在types目录下。 使用场景 在ts文件中对引用的外部库做…

汇编逻辑运算指令

目录 逻辑运算指令 一&#xff1a;取反指令NOT 二&#xff1a;逻辑与运算AND&#xff08;重点&#xff09; 屏蔽某些位. 把小写字母转换成大写字母 判断一个数的状态 三&#xff1a;逻辑或运算指令OR 用于拼字 把大写字母转换为小写字母 四&#xff1a;逻辑异或指令XOR…

程序员也会八卦吗?

世俗的眼光&#xff0c;总是觉得女生喜欢吃八卦&#xff0c;经常聚在一起小圈子叽叽喳喳谈论朋友圈。 其实&#xff0c;从现实来看&#xff0c;办公室的男性同胞也不啻于女生的八卦程度。 在吃瓜这件问题上&#xff0c;程序员凭借自身的技术优势&#xff0c;往往奋战于最前线…

【网络编程】捕获网卡IP数据报

本文将通过winsock从应用层捕捉网络层的IP数据报。 唉&#xff0c;原来的时候一直希望能在应用层实现网络游戏加速&#xff0c;发现可以捕捉网卡IP数据报后觉得可能有希望写出来。后面想了想得出结论&#xff1a;可以捕获没卵用&#xff0c;因为没法拦截&#xff08;包已经发出…

RocketMQ的事务消息是如何实现的?

RocketMQ的事务消息实现方法如下&#xff1a; 1、首先生产者订单系统先发送⼀条half消息到Broker&#xff0c;half消息对消费者而⾔是不可⻅的 2、再创建订单&#xff0c;根据创建订单成功与否&#xff0c;向Broker发送commit或rollback 3、并且⽣产者订单系统还可以提供Broker…

Spark 3.0 - 11.ML 随机森林实现二分类实战

目录 一.引言 二.随机森林实战 1.数据预处理 2.随机森林 Pipeline 3.模型预测与验证 三.总结 一.引言 之前介绍了 决策树 &#xff0c;而随机森林则可以看作是多颗决策树的集合。在 Spark ML 中&#xff0c;随机森林中的每一颗树都被分配到不同的节点上进行并行计算&…

Crack:Aspose.3D for .NET 22.11.X

Aspose.3D for .NETAspose.3D for .NET 是一个功能丰富的游戏软件和计算机辅助设计 (CAD) API&#xff0c;无需任何 3D 建模和渲染软件依赖即可操作文档。API 支持 Discreet3DS、WavefrontOBJ、FBX&#xff08;ASCII、二进制&#xff09;、STL&#xff08;ASCII、二进制&#x…

[附源码]Nodejs计算机毕业设计基于web的家教管理系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

linux信号:SIGINT、SIGKILL、SIGSTOP、SIGCONT

目录 1. SIGINT 2. SIGKILL 3. SIGSTOP与SIGCONT 简介 SignalStandardActionCommentSIGINTP1990TermInterrupt form keybordSIGKILLP1990TermKill signalSIGSTOPP1990TermInterrupt form keybord1. SIGINT 我们在shell交互式进程中常用的ctrl c 就是对当前运行的程序进行…

[附源码]Node.js计算机毕业设计电影票网上订票系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

2022年山东食品安全管理员模拟试题及答案

百分百题库提供食品安全管理员考试试题、食品安全管理员考试预测题、食品安全管理员考试真题、食品安全管理员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 一、单选题 1.下列哪项措施与保证食品安全无关&#xff1f; A…

2022gwb_web3

可以通过反序列化出一个 Webclome 类从而任意构造原生类&#xff0c;但只能调用 getSize 方法获取文件或目录 的大小&#xff0c;试了试直接拿根目录的 /flag 就别想了&#xff0c;先看看网站目录有没有藏什么东西&#xff08;扫目录什么也扫 不出来&#xff09;&#xff0c;EX…

再学C语言2:概览

重新把C语言梳理一遍&#xff0c;学习在VSCode中进行C语言编程 一、C语言起源 1972年&#xff0c;贝尔实验室的Dennis Ritchie在C语言的基础上设计出一种新的语言&#xff0c;即C语言 C是作为从事实际编程工作的程序员的一种工具儿出现&#xff0c;是为编程人员开发的语言 二…

【脚本项目源码】Python制作桌面宠物,这么可爱的萌宠你不想拥有吗?

前言 本文给大家分享的是如何通过利用Python制作桌面宠物&#xff0c;废话不多直接开整~ 开发工具 Python版本&#xff1a; 3.6 相关模块&#xff1a; random模块 os模块 cfg模块 sys模块 PyQt5模块 环境搭建 安装Python并添加到环境变量&#xff0c;pip安装需要的相…

skynet设计原理和使用

skynet设计原理一、多核并发编程方式二、skynet2.1、skynet简介2.2、环境准备2.3、编译安装2.4、Actor 模型2.5、消息队列2.6、actor公平调度三、skynet的使用3.1、第一个skynet程序3.2、skynet网络消息3.3、skynet定时消息3.4、skynet actor间消息四、vscode调试skynet总结后言…